世界球精选!0.1 + 0.2 != 0.3:Is floating point math broken?
本文收录于 www.cswiki.top
(资料图)
看下面这段代码
0.1+0.2==0.3->Output:false0.1+0.2->Output:0.30000000000000004
0.1 + 0.2 != 0.3,什么情况?
先上答案:0.1 + 0.2 != 0.3 这个问题的症结在于:在现今的计算机中,数字的最终存储(表示)格式是二进制,是整数乘以 2 的幂。所以一切分母不是 2 的幂的有理数(例如 0.1,即 1/10)都是无法被计算机精确表示的。
下面来详细分析:
十进制小数与二进制的转换整数十进制转二进制大伙都知道(除 2 取余法),我们来看看小数是怎么转二进制的
小数部分的转换不同于整数部分,它采用的是乘 2 取整法:将十进制中的小数部分乘以 2,得到一个数,将这个数的整数位作为二进制的一位,然后继续取其小数部分乘以 2 作为下一位,直到不存在小数为止
举个例子:3.14(十进制)
整数部分:
3(十进制)-> 0011(二进制)小数部分:
0.14 x 2 = 0.28(将十进制 3中的小数部分 0.14乘以 2,得到一个数 0.28,将这个数的整数位 0作为二进制的一位,然后继续取其小数部分乘以 2 作为下一位,直到不存在小数为止),此时小数部分的二进制表示是 0xxx xxxx0.28 x 2 = 0.56(将十进制 0.28中的小数部分 0.28乘以 2,得到一个数 0.56,将这个数的整数位 0作为二进制的一位,然后继续取其小数部分乘以 2 作为下一位,直到不存在小数为止),此时小数部分的二进制表示是 00xx xxxx0.56 x 2 = 1.12(将十进制 0.56中的小数部分 0.56乘以 2,得到一个数 1.12,将这个数的整数位 1作为二进制的一位,然后继续取其小数部分乘以 2 作为下一位,直到不存在小数为止),此时小数部分的二进制表示是 001x xxxx.......问题就出现了~
如果小数部分一直没法变成 0,那么小数部分的二进制表示将是无穷无尽的。
由于计算机的资源是有限的,所以没办法用二进制精确的表示这些小数部分一直没法变成 0 的数,只能用【近似值】来表示(现在基本采用的都是 IEEE 754 标准,https://en.wikipedia.org/wiki/IEEE_754#Basic_and_interchange_formats),这不可避免地就会造成精度缺失
Working with Floats in Programming在平常写代码的时候,这个精度问题意味着我们需要使用舍入函数将浮点数四舍五入到我们需要的小数位,然后再显示它们。
还需要用【允许一定差距(allow some amount of tolerance)的比较】来替换浮点数之间的相等比较 ==,这意味着:
不要使用:if (x == y) { ... }
而是使用:if (abs(x - y) < myToleranceValue) { ... }
心之所向,素履以往,我是小牛肉,小伙伴们下篇文章再见
回复『春秋招』我拉你进交流群
相关阅读
-
世界热推荐:今晚7:00直播丨下一个突破...
今晚19:00,Cocos视频号直播马上点击【预约】啦↓↓↓在运营了三年... -
NFT周刊|Magic Eden宣布支持Polygon网...
Block-986在NFT这样的市场,每周都会有相当多项目起起伏伏。在过去... -
环球今亮点!头条观察 | DeFi的兴衰与...
在比特币得到机构关注之后,许多财务专家预测世界将因为加密货币的... -
重新审视合作,体育Crypto的可靠关系才能双赢
Block-987即使在体育Crypto领域,人们的目光仍然集中在FTX上。随着... -
简讯:前端单元测试,更进一步
前端测试@2022如果从2014年Jest的第一个版本发布开始计算,前端开发... -
焦点热讯:刘强东这波操作秀
近日,刘强东发布京东全员信,信中提到:自2023年1月1日起,逐步为...