因为说了句金额用double表示,结果被踢出群聊

浮点型变量在进行计算的时候会出现丢失精度的问题,所以,在需要用到金钱的地方要用BigDecimal而不是其他,如下代码段。

public class Main {
    public static void main(String[] args)  {
        System.out.println(0.05+2.05);
        System.out.println(1.5-1.05);
        System.out.println(1.0455*100);
        System.out.println(123.3 / 100);
    }
}

输出:

2.0999999999999996
0.44999999999999996
104.55000000000001
1.2329999999999999

如果用浮点表示,那么我们在进行商品价格计算的时候,就会出现问题,可能我们有0.06元,却无法购买一个0.05元和一个0.01元的商品,因为他们两个的总和可能为0.060000000000000005。

所以,一般我们用BigDecimal来表示金额,当然在数据库中也要使用decimal,不用float或double,也可以用用int或者long存储金额,单位为”分“。

但是BigDecimal使用不当也会造成精度丢失,下面是BigDecimal的部分构造器,以及常用方法。

BigDecimal(int)       创建一个具有参数所指定整数值的对象。
BigDecimal(double)    创建一个具有参数所指定双精度值的对象。
BigDecimal(long)      创建一个具有参数所指定长整数值的对象。
BigDecimal(String)    创建一个具有参数所指定以字符串表示的数值的对象。
add(BigDecimal)       BigDecimal对象中的值相加,然后返回这个对象。
subtract(BigDecimal)  BigDecimal对象中的值相减,然后返回这个对象。
multiply(BigDecimal)  BigDecimal对象中的值相乘,然后返回这个对象。
divide(BigDecimal)    BigDecimal对象中的值相除,然后返回这个对象。
toString()            将BigDecimal对象的数值转换成字符串。
doubleValue()         将BigDecimal对象中的值以双精度数返回。
floatValue()          将BigDecimal对象中的值以单精度数返回。
longValue()           将BigDecimal对象中的值以长整数返回。
intValue()            将BigDecimal对象中的值以整数返回。

如下测试代码,结果貌似更为过分。

public class Main {
    public static void main(String[] args)  {
        BigDecimal bigDecimal1 = new BigDecimal(0.05);
        BigDecimal bigDecimal2 = new BigDecimal(0.01);

        BigDecimal bigDecimal3 = new BigDecimal(122.11);

        System.out.println(bigDecimal1.add(bigDecimal2));
        System.out.println(bigDecimal3.toString());
    }
}

输出结果:

0.06000000000000000298372437868010820238851010799407958984375
122.1099999999999994315658113919198513031005859375

其实也好解决,使用他的BigDecimal(String)构造方法即可。

public class Main {
    public static void main(String[] args)  {
        BigDecimal bigDecimal1 = new BigDecimal("0.05");
        BigDecimal bigDecimal2 = new BigDecimal("0.01");
        BigDecimal bigDecimal3 = new BigDecimal("122.11");
        System.out.println(bigDecimal1.add(bigDecimal2));
        System.out.println(bigDecimal3.toString());
    }
}

输出结果:

0.06
122.11

所以我们一般使用BigDecimal来解决商业运算上丢失精度的问题的时候,声明BigDecimal对象的时候一定要使用它构造参数为String的类型的构造器。

其实,在BigDecimal(double val)构造器上是有注释已经说明了这个问题的,大概意思是说,如果有人使用new BigDecimal(0.1)创建一个BigDecimal对象,那他的实际值等于0.1000000000000000055511151231257827021181583404541015625,但如果使用new BigDecimal("0.1")这样去创建,则最终值会是你可预测的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章