携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第18天,点击查看活动详情
一个简单的面试题:
>>>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 位):