一个简单的面试题:
>>>0.1+0.1+0.1 0.2 >>>0.1+0.1+0.1 0.30000000000000004 >>>0.1+0.1+0.1-0.3 5.551115123125783e-17
下面一个简单的例子:
a = 0.0 for i in range(10): print(a) a+=0.1
结果: 打印0.1 连续相加10次,会显示不同的值,既是精度损失造成的.
另外一个问题:(精度控制)
关于小数和取整->高精度---低精度 round()
1. 不指定小数点位数, 即取整数, 四舍五入: (取到哪一位的后面一位, 若遇到.5 奇进偶不进)
round(2.3) -2.0 round(2.6) -3.0 round(2.5) -3.0 round(1.5) -2.0
2. 指定小数点位数, 即有小数位, 四舍五入: (取到哪一位的后面一位, 若遇到.5 偶进奇不进)
round(2.635,2) -2.63 round(2.645,2) -2.65 round(2.655,2) -2.65 round(2.665,2) -2.67 round(2.675,2) -2.67
3. math模块的ceil(x)
取大于或者等于x的最小整数.
4. math模块的floor(x)
取小于或者等于x的最大整数.
f = 11.2 math.floor(f) 向下取整 #11.0 math.ceil(f) 向上取整 #12.0
>>> x = 0.0 >>> for i in range(10): x += 0.1 print(x) 0.1 0.2 0.30000000000000004 0.4 0.5 0.6 0.7 0.7999999999999999 0.8999999999999999 0.9999999999999999
即:为什么有几行的输出看起来不对?
因为 Python 中使用双精度浮点数来存储小数。在 Python 使用的 IEEE 754 标准(52M/11E/1S)中,8字节64位存储空间分配了52位来存储浮点数的有效数字,11位存储指数,1位存储正负号,即这是一种二进制版的科学计数法格式。虽然52位有效数字看起来很多,但麻烦之处在于,二进制小数在表示有理数时极易遇到无限循环的问题。其中很多在十进制小数中是有限的,比如十进制的 1/10,在十进制中可以简单写为 0.1 ,但在二进制中,他得写成:
0.0001100110011001100110011001100110011001100110011001…..(后面全是 1001 循环)。因为浮点数只有52位有效数字,从第53位开始,就舍入了。这样就造成了标题里提到的”浮点数精度损失“问题。 舍入(round)的规则为“0 舍 1 入”,所以有时候会稍大一点有时候会稍小一点。
Python 的浮点数类型有一个 .hex()方法,调用能够返回该浮点数的二进制浮点数格式的十六进制版本。这话听着有点绕,其实是这样的:本来浮点数应该有一个 .bin() 方法,用来返回其二进制浮点数格式。如果该方法存在的话,它看起来就像这样(p-4表示×2-4,或者可以简单理解为小数点 左移 4 位):