今天在做接口传保费的时候出现了一个奇怪的问题,double类型保费变成了一大长串的非精准保费,甚至奇怪,难道是java的bug?最后通过度娘找到了答案

话不多说,先看如下代码public final class Person {

public static void main(String[] args) {

double a1 = 0.06;

double a2 = 0.01;

System.out.println(a1);

System.out.println(a2);

System.out.println(a2 + a1);

}

}

结果并不是0.07,而是0.06999999999999999

你认为你看错了,但结果却是是这样的。问题在哪里呢?原因在于我们的计算机是二进制的。浮点数没有办法是用二进制进行精确表示。我们的CPU表示浮点数由两个部分组成:指数和尾数,这样的表示方法一般都会失去一定的精确度,有些浮点数运算也会产生一定的误差。如:2.4的二进制表示并非就是精确的2.4。反而最为接近的二进制表示是 2.3999999999999999。浮点数的值实际上是由一个特定的数学公式计算得到的。

其实Java的float只能用来进行科学计算或工程计算,在大多数的商业计算中,一般采用java.math.BigDecimal类来进行精确计算。

如何使用这个BigDecimal呢,拢共分三步,

一.用float或者double变量构建BigDecimal对象

构建有两种方法:1.BigDecimal b1 =newBigDecimal(xxx); xxx可以是double类型,也可以是string类型

2.BigDecimal b2 = BigDecimal.valueOf(xxx); xxx 只能是数值类型

注意:推荐使用第一种方法,并采用string类型进行构建。否则还是会出现2.0809999999999的情况。

二.通过调用BigDecimal的加,减,乘,除等相应的方法进行算术运算public BigDecimal add(BigDecimal value); //加法

public BigDecimal subtract(BigDecimal value); //减法

public BigDecimal multiply(BigDecimal value); //乘法

public BigDecimal divide(BigDecimal value); //除法

三.把BigDecimal对象转换成float,double,int等类型double a1 = b2.doubleValue();

float a2 = b2.floatValue();

直接通过BigDecimal 进行计算比较麻烦,可以封装一层,简化使用


版权声明:本文为weixin_30051655原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/weixin_30051655/article/details/114057023