Java

1、多精度计算问题

多精度不能直接计算,会存在精度缺失的问题。

  1. public static void main (String[] args) {
  2. double num1 = 1;
  3. double num2 = 31.2;
  4. double num3 = 323.03;
  5. System.out.println (num1+num2+num3);
  6. /**
  7. * 355.22999999999996
  8. */
  9. }

如上代码,3 个数值想加之后却得出了一个很长的数值。
在 java 开发中可以通过 BigDecimal 进行数值类型的计算,详细可到 BigDecimal 工具类。
数据库也是一样,MySQL中有floatdouble类型,通过sql直接累加数据也会有精度缺失的情况。如果要精确的数值计算,要使用MySQL的decimal类型。

2、包装类型比对

  1. public static void main(String[] args) {
  2. Integer i1 = 100;
  3. Integer i2 = 100;
  4. Integer i3 = 200;
  5. Integer i4 = 200;
  6. System.out.println(i1==i2); // true
  7. System.out.println(i3==i4); // false
  8. }

如上代码很神奇,同样是数值比对100的时候可以通过双等号返回true。200就返回false
这是因为IntegervalueOf()方法。

  1. //Integer的valueOf方法
  2. public static Integer valueOf(int i) {
  3. if (i >= IntegerCache.low && i <= IntegerCache.high)
  4. return IntegerCache.cache[i + (-IntegerCache.low)];
  5. return new Integer(i);
  6. }

[-128,128]之间的数,可以通过双等于比对成功,之外的数值就会返回一个new一个新的Integer,因此会返回false。
Double的比较就简单一点,双等于比对全是false。这是因为Double直接是返回了一个新的Double

  1. //Double的valueOf方法
  2. public static Double valueOf(String s) throws NumberFormatException {
  3. return new Double(parseDouble(s));
  4. }

在数值比对的时候乱的样子,他们都有eq方法,通过这个方法比对可以吗?
可以的,不管是Integer还是Double都存在一个equals方法,通过这个方法即可进行数值比对。但是这个方法不是很完美。

  1. public static void main (String[] args){
  2. Double i1 = 100d;
  3. System.out.println(i1.equals("100"));
  4. //false
  5. }

如上所示,因为太多的人都知道字符串类型不能用双等号进行比对,要用eq方法进行比对其value。
这样会让很多人误以为IntegerDouble类型也是如此,而且在编码的时候如上这种写法也没有报错,会认为都是100肯定会返回true。恰巧这种想法是错误的。

  1. public boolean equals(Object obj) {
  2. return (obj instanceof Double)
  3. && (doubleToLongBits(((Double)obj).value) ==
  4. doubleToLongBits(value));
  5. }

Doubleeq方法入参是Object类型,因此不管传入什么类型都不会报错。i1.equals("100")这种就是双精度和字符进行比对,这两个永远都不可能返回true。正确的写法应该是i1.equals(100d)
但是尽管多次提醒,但是还是会有不认真的开发小伙伴错误,因此,可以使用Double.compareTo方法,这个方法和eq方法类似,但是有编译的异常,这样可有效的提醒开发人员。

  1. public static void main (String[] args){
  2. Double i1 = 100d;
  3. System.out.println(i1.compareTo (100d)); //0
  4. System.out.println(i1.compareTo (1d)); //1
  5. }

3、除以0会怎样?

小学的时候就讲过,进行除法运算时,除以0是没有意义的,开发过程中也是如此, 发现可能存在除以0的场景要特别注意,程序不会抛出异常,竟然会返回一个字符串!虽然这种场景不多,但是还是需要了解一下。

1除以0的场景

  1. public static void main(String[] args) {
  2. Double d = 1d;
  3. double v = d / 0d;
  4. System.out.println(v);
  5. //Infinity
  6. }

0除以0的场景

  1. public static void main(String[] args) {
  2. Double d = 0d;
  3. double v = d / 0d;
  4. System.out.println(v);
  5. //NaN
  6. }

4、float转double

  1. public static void main(String[] args) {
  2. Float f = 12312.12f;
  3. System.out.println(f.doubleValue());
  4. System.out.println(Double.parseDouble (f.toString ()));
  5. //12312.1201171875
  6. //12312.12
  7. }

Float类中有一个doubleValue方法,返回值是一个double类型,这样会很容易的以为这是float转换double类型。但是转换之后精度缺失了,只能换一种方式转换。