欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

解决0.1+0.2≠0.3的问题

程序员文章站 2022-04-07 18:23:20
0.1+0.2≠0.3问题先跑一段Java代码:出BUG了吗???刚学习编程的小伙伴可能会摸不着头脑,经过测试这个问题同样的也会出现在如c/c++,JS,python语言中。原因分析其实,这并不是出Bug了,只是因为计算机无法100%准确地存储如0.1、0.2这样的小数,进而导致两个数进行加法运算返回的结果精度也可能会跟着出现问题。下面有更详细的分析:1.首先了解十进制化二进制的原则:(1)整数部分对2取余然后逆序排列。(2)小数部分乘2取整数部分,然后顺序排列。2.先来尝试把十进制的0....

相信小伙伴们在编程的时候会遇到这种问题,在进行浮点数运算有时得到结果会带有一个"小尾巴",就像下面这样:
先跑一段Java代码:
解决0.1+0.2≠0.3的问题

出BUG了吗???
刚学习编程的小伙伴可能会摸不着头脑,经过测试这个问题同样的也会出现在如c/c++,JS,python语言中。

原因分析

其实,这并不是出Bug了,只是因为计算机无法100%准确地存储如0.1、0.2这样的小数,进而导致两个数进行加法运算返回的结果精度也可能会跟着出现问题。下面有更详细的分析:

1.首先了解十进制化二进制的原则:

(1)整数部分对2取余然后逆序排列。(2)小数部分乘2取整数部分,然后顺序排列。

2.先来尝试把十进制的0.1化成二进制得到:

0.1(十进制)= 0.0001100110011…0011…(二进制)
结果将不断循环0011这个片段,计算机将永远都存不下0.1的二进制小数,这就是问题所在了。像单精度浮点型数据用32位存储,双精度浮点型用64位存储,但是它们始终是有限位数,用来存储0.1将不可避免出现精度缺失的问题。只有当存储如1/2、1/4、1/8、3/4、5/8…这种形式的小数时才能准确。所以又推断0.2也会出现无限循环的情况,而结果也确实如此:
0.2(十进制)= 0.0011001100110011…0011…(二进制)

3.另外尝试其他情况如双精度浮点型的0.1+0.3:

解决0.1+0.2≠0.3的问题

还有单精度浮点型的0.1+0.2:

解决0.1+0.2≠0.3的问题

所以并不是只要出现0.1或0.2等的浮点数运算就会一定会出现精度缺失,我们也无法预测到所有可能会出现精度缺失的情况,所以找到解决办法来避免在进行涉及浮点数运算的时候出现这种“意外”才是最重要的。

解决办法

通过保留小数点位数,剔除结果可能出现的“小尾巴”即可:
下面提供Java以及JS保留小数点位数的示例:

1.Java解决方案:

public static void main(String[] args){
    double a = 0.1d;
    double b = 0.2d;
    double c = a+b;
    BigDecimal big = new BigDecimal(c);
    double result1 = big.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();//转成double
    String result2 = big.setScale(2,BigDecimal.ROUND_HALF_UP).toString();//转成String
    System.out.println(result1);
    System.out.println(result2);
}

2.JS解决方案:

function test(){
    var a = 0.1;
    var b = 0.2;
    var c = a+b;
    console.info(toFixed(c,2))
}
/*
* 对num保留小数点后digit位并返回
*/
function toFixed(num,digit){
    var times = Math.pow(10, digit);
    var roundNum = Math.round(num * times) / times;
    return roundNum.toFixed(digit);
}

收工!

本文地址:https://blog.csdn.net/Liuyundssda/article/details/110455188

相关标签: java javascript