06. 编程语言 - 缺陷篇
大约 1 分钟
06. 编程语言 - 缺陷篇
目录
[toc]
0.1+0.2 = 0.30000000000000004
参考:https://www.runoob.com/manual/pythontutorial3/docs/html/floatingpoint.html
类似情况,相同原理的还有:
- 运算结果为0.3时
3*0.1 = 0.30000000000000004 != 0.3
- 浮点加减运算
50.25f + 11.17f = 61.419998
50.25f - 11.14f = 39.080002
- 运算结果为0.3时
普遍性
- 所有语言都存在这种问题(亲测
python
、javascript
存在) - 但计算器一般不会这样(亲测
casio fx82
、uTools计算稿纸
、微软计算器
、安卓多多计算器
无该问题)
- 所有语言都存在这种问题(亲测
原理(以双浮点为例,小数点后面有效数字16位)
- 0.1 = 0.0001100110011001
- 0.2 = 0.0011001100110011
- 0.3 = 0.0100110011001100
- 0.1+0.2 = 0.0100110011001100 = 0.3
- 即:
解决方案
比如Python中,float.as_integer_ratio() 方法以分数的形式表示一个浮点数的值:
>>> x = 3.14159 >>> x.as_integer_ratio() (3537115888337719, 1125899906842624) >>> x == 3537115888337719 / 1125899906842624 True
float.hex() 方法以十六进制表示浮点数,给出的同样是计算机存储的精确值:
>>> x.hex() '0x1.921f9f01b866ep+1' >>> x == float.fromhex('0x1.921f9f01b866ep+1') True
另外一个有用的工具是 math.fsum() 函数,它帮助求和过程中减少精度的损失。当数值在不停地相加的时候,它会跟踪“丢弃的数字”。这可以给总体的准确度带来不同,以至于错误不会累积到影响最终结果的点:
>>> sum([0.1] * 10) == 1.0 False >>> math.fsum([0.1] * 10) == 1.0 True
手持两把锟斤拷 口中疾呼烫烫烫 脚踏千朵屯屯屯 笑看万物锘锘锘
- C语言