相等,还是不等(1) - 0.1 + 0.2 = 0.30000000000000004
入门。
比较两个数, 用 ==
。
jshell> 1 + 1 == 2
$1 ==> true
jshell> 1 + 1 + 1 == 3
$2 ==> true
放弃?
到了小数好像就不太对了:
jshell> 0.1 == 0.1
$3 ==> true
jshell> 0.1 + 0.1 == 0.2
$1 ==> true
jshell> 0.1 + 0.1 + 0.1 == 0.3
$2 ==> false
是 Java 的 bug?Python 好像也一样:
>>> 0.1 + 0.1 == 0.2
True
>>> 0.1 + 0.1 + 0.1 == 0.3
False
其他一些例子: 2.0 - 1.1 应该是 0.9,对吗?
>>> 2.0 - 1.1
0.8999999999999999
1.0 / 0.1 == 10, 所以 1.0 % 0.1 应该是 0,对吗?
>>> 1.0 % 0.1
0.09999999999999995
进阶!
计算机世界的 0.1 并不是真正的 0.1,而是比 0.1 稍大一点点。我们多打印出来几位小数看看:
>>> '%.60f' % 0.1
'0.100000000000000005551115123125782702118158340454101562500000'
所以 1.0/0.1 并不是 10,而是只够 9 个"0.1",剩下了 0.09999999999999995
正因为浮点数这种特性,在高精度计算,或涉及到钱的时候,不能直接使用浮点数。
解决方案:
- 把浮点数转换为整数,比如把金额乘以 100,然后当成整数进行计算,只是单位变成了“分”而不是“元”
- 用特殊的类,比如 Java 的 BigDecimal 或 Python 的 Decimal
Python:
>>> from decimal import Decimal
>>> Decimal(1.0) % Decimal(0.1)
Decimal('0.09999999999999995003996389187')
>>> Decimal('1.0') % Decimal('0.1')
Decimal('0.0')
>>> Decimal('2.0') - Decimal('1.1')
Decimal('0.9')
Java:
jshell> new BigDecimal("2.00").subtract(new BigDecimal("1.10"))
$1 ==> 0.90
由于 0.1+0.2=0.30000000000000004
,有一个专门的网站讨论这个问题:https://0.30000000000000004.com/