一个关于浮点数运算须要注意的地方

1 a = 4.2
2 b = 2.1
3 
4 a + b
5 
6 (a + b) == 6.3 

  浮点数存在的一个问题,不能精确的表示十进制数。这是因为底层 CPU 和  IEEE 754 标准经过本身的浮点单位去执行算术时的特征。看似有穷的小数, 在计算机的二进制表示里倒是无穷的。其实这不是Python的问题,而是实数的无限精度跟计算机的有限内存之间的矛盾。spa

  举个例子,假如说我只能使用整数(即只精确到个位,计算机内的浮点数也只有有限精度,以C语言中的双精度浮点数double为例,精度为52个二进制位),要表示任意实数(无限精度)的时候我就只能经过舍入(rounding)来近似表示。3d

  好比1.2我会表示成1,2.4表示成2,3.6表示成4.code

  因此呢?blog

  在算1.2 - 1.2的时候,因为计算机表示的问题,我算的其实是1 - 1,结果是0,碰巧蒙对了;内存

  在算1.2 + 1.2 - 2.4的时候,因为计算机表示的问题,我算的其实是1 + 1 - 2,结果是0,再次蒙对了;ci

  可是在算1.2 + 1.2 + 1.2 - 3.6的时候,因为计算机表示的问题,我算的其实是1 + 1 + 1 - 4,结果是-1,运气没那么好啦!字符串

  这里的1.2, 2.4, 3.6就至关于你问题里的0.1, 0.2和0.3,1, 2, 4则是真正在计算机内部进行运算的数值,我说清楚了吗?数学

  另:不单单是浮点数的在计算机内部的表示有偏差,运算自己也可能会有偏差。好比整数2能够在计算机内准确表示,可是要算根号2就有偏差了;再好比两个浮点数相除,原本两个数都是精确表示的,但除的结果精度却超出了计算机内实数的表示范围,而后就有偏差了。class

  通常状况下,这一点点的小偏差是容许存在的。若是不能容忍这种偏差(好比金融领域),那么就要考虑用一些途径来解决这个问题了。import

  使用Decimal模块就能够解决这个问题。

1 from decimal import Decimal
2 a = Decimal('4.2')
3 b = Decimal('2.1')
4 a + b
5 
6 print(a + b)
7 
8 (a + b) == Decimal('6.3')

  

  尽管代码看起来比较奇怪,使用字符串来表示数字,可是 Decimal 支持全部经常使用的数学运算。总的来讲,当涉及金融领域时,哪怕是一点小小的偏差在计算过程当中都是不容许的。所以 decimal 模块为解决这类问题提供了方法。

相关文章
相关标签/搜索