关于java:电商金额计算的-4-个坑千万注意了

32次阅读

共计 2579 个字符,预计需要花费 7 分钟才能阅读完成。

作者:叁滴水

起源:https://blog.csdn.net/qq_3028…

前言

电商我的项目开发时必定少不了金额计算,金额计算时有很多让人坑人的中央,在此记录,免得被坑。

1、多精度计算问题

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

public static void main (String[] args) {
  double num1 = 1;
  double num2 = 31.2;
  double num3 = 323.03;
  System.out.println (num1+num2+num3);
  /**
   * 355.22999999999996
   */
}

如上代码,3 个数值想加之后却得出了一个很长的数值。

在 java 开发中能够通过 BigDecimal 进行数值类型的计算,具体可到 BigDecimal 工具类。

数据库也是一样,mysql 中有 float 和 double 类型,通过 sql 间接累加数据也会有精度缺失的状况。如果要准确的数值计算,要应用 mysql 的 decimal 类型。

2、包装类型比对

public static void main(String[] args) {
     Integer i1 = 100;
     Integer i2 = 100;
     Integer i3 = 200;
     Integer i4 = 200;
     System.out.println(i1==i2); // true
     System.out.println(i3==i4);  // false
}

如上代码很神奇,同样是数值比对 100 的时候能够通过双等号返回 true。200 就返回 false。

这是因为 Integer 的 valueOf()办法。

//Integer 的 valueOf 办法
public static Integer valueOf(int i) {if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

在 [-128,128] 之间的数,能够通过双等于比对胜利,之外的数值就会返回一个 new 一个新的 Integer,因而会返回 false。

Double 的比拟就简略一点,双等于比对全是 false。这是因为 Double 间接是返回了一个新的 Double。
//Double 的 valueOf 办法
public static Double valueOf(String s) throws NumberFormatException {return new Double(parseDouble(s));
}

在数值比对的时候乱的样子,那我发现他们都有 eq 办法,通过这个办法比对能够吗?

能够的,不论是 Integer 还是 Double 都存在一个 equas 办法,通过这个办法即可进行数值比对。然而这个办法不是很完满。

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

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

public boolean equals(Object obj) {return (obj instanceof Double)
           && (doubleToLongBits(((Double)obj).value) ==
                  doubleToLongBits(value));
}

Double 的 eq 办法入参是 Object 类型,因而不论传入什么类型都不会报错。i1.equals (“100”)这种就是双精度和字符进行比对,这两个永远都不可能返回 true。正确的写法应该是 i1.equals (100d)。

然而只管屡次揭示,然而还是会有不认真的开发小伙伴谬误,因而,能够应用 Double.compareTo 办法,这个办法和 eq 办法相似,然而有编译的异样,这样可无效的揭示开发人员。

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

3、除以 0 会怎么?

小学的时候就讲过,进行除法运算时,除以 0 是没有意义的,开发过程中也是如此,发现可能存在除以 0 的场景要特地留神,程序不会抛出异样,居然会返回一个字符串!尽管这种场景不多,然而还是须要理解一下。

1 除以 0 的场景:

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

0 除以 0 的场景:

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

4、float 转 double

public static void main(String[] args) {
    Float f = 12312.12f;
    System.out.println(f.doubleValue()); 
    System.out.println(Double.parseDouble (f.toString ())); 
    //12312.1201171875
    //12312.12
}

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

近期热文举荐:

1.600+ 道 Java 面试题及答案整顿(2021 最新版)

2. 终于靠开源我的项目弄到 IntelliJ IDEA 激活码了,真香!

3. 阿里 Mock 工具正式开源,干掉市面上所有 Mock 工具!

4.Spring Cloud 2020.0.0 正式公布,全新颠覆性版本!

5.《Java 开发手册(嵩山版)》最新公布,速速下载!

感觉不错,别忘了顺手点赞 + 转发哦!

正文完
 0