浅色年华的gravatar头像
浅色年华2017-07-11 16:50:48
java中进行高精度精准计算

今天在做接口传保费的时候出现了一个奇怪的问题,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 = new BigDecimal(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对象转换成floatdoubleint等类型

        double a1 = b2.doubleValue();
        float a2 = b2.floatValue();

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


打赏

分享到:

最近浏览
a3870764722a2017年10月18日
最代码贡献等级说明
无名指2017年10月18日
暂无贡献等级
zuiDMxin2017年10月12日
暂无贡献等级
3737170962017年9月22日
最代码贡献等级说明
wcy55552017年9月22日
最代码贡献等级说明
toney_shen2017年9月7日
最代码贡献等级说明
q28238652017年9月6日
暂无贡献等级
junwuxie2017年9月1日
最代码贡献等级说明
庸人自扰2017年8月17日
暂无贡献等级
小恶魔2017年8月16日
最代码贡献等级说明
zhaoshuting2017年8月10日
最代码贡献等级说明
醉美猴王 LV22017年8月8日
最代码贡献等级说明
JiangBigPan2017年8月2日
最代码贡献等级说明
yulinfeng2017年8月2日
最代码贡献等级说明
a10166647362017年8月2日
最代码贡献等级说明
sc9368662017年8月1日
暂无贡献等级
wsh5644940622017年8月1日
最代码贡献等级说明
风它没有枝2017年7月31日
暂无贡献等级
zsdnishishui2017年7月30日
最代码贡献等级说明
巳卅丶April2017年7月28日
暂无贡献等级
顶部客服微信二维码底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友