python中的浮点运算


>>> .1+.1+.1+.1 ==.4
True
>>> .1+.1+.1 ==.3
False
>>> 

以上是python解释器的输出。我理解这样一个事实,
浮点算术是使用基数2完成的,并以二进制形式存储在
中,因此上述计算结果的差异。
现在我发现。4 = .011(0011)[()里面的数字无限重复,这是这个分数的二进制
表示],因为它不能被精确地存储,一个近似值
将被存储。
类似0.3 = 0.01 (0011)
所以0.4和0.3不能完全存储在内部。
然后python返回的原因首先是真和第二个假
_______________________________________________________________________________
我做了一些研究,发现如下:
>>> Decimal(.4)
Decimal('0.40000000000000002220446049250313080847263336181640625')
>>> Decimal(.1+.1+.1+.1)
Decimal('0.40000000000000002220446049250313080847263336181640625')
>>> Decimal(.1+.1+.1)
Decimal('0.3000000000000000444089209850062616169452667236328125')
>>> Decimal(.3)
Decimal('0.299999999999999988897769753748434595763683319091796875')
>>> Decimal(.1)
Decimal('0.1000000000000000055511151231257827021181583404541015625')

这可能解释了为什么加法是按照
的方式进行的,假设Decimal给出了存储在

下面的数字的确切输出

那么python返回第一个为True而第二个为False的原因是什么呢因为两者不能比较

浮点数绝对可以比较是否相等。只有当您期望通过近似计算来保持精确等式时,才会出现问题。但是浮点相等比较的语义是完全定义好的。

当你在程序中编写0.1时,它被四舍五入到最接近的IEEE 754二进制64浮点数,即实数0.1000000000000000055511151231257827021181583404541015625,或者十六进制记数法中的0x1.99999999999999ap−4 (' p−4 '部分表示× 2⁻⁴)。每一个(正常的)binary64浮点数都是一个形式为±2 ×(1 +𝑓/2³)的实数,其中𝑛和𝑓是整数,−1022≤𝑛≤1023,0≤𝑓<2⁵³;这是最接近0.1的数字。

当你在浮点运算中将其相加三次时,确切的结果0.3000000000000000166533453693773481063544750213623046875被四舍五入为0.3000000000000000444089209850062616169452667236328125或0x1.333333334p−2(因为只有53位精度可用),但是当你写0.3时,你得到0.29999999999999999988897769753748434595763683319091796875或0x1.33333333333p−2稍微接近0.3。

然而,四倍0.1000000000000000055511151231257827021181583404541015625或0x1.99999999999999ap−4等于0.4000000000000000222044604925031308084726333618164062500或0x1.999999999999ap−2,这也是最接近0.4的浮点数,因此是你在程序中编写0.4时得到的结果。因此,当您写4*0.1时,结果是与您写0.4时完全相同的浮点数。

现在,你没有写4*0.1,而是写.1 + .1 + .1 + .1。但是在二进制浮点运算中有一个定理x + x + x + x——也就是fl(fl(fl(s1 + s1) + s1) + s1))——总是得到不舍入的4个整数(除非它溢出了),尽管x + x + x或fl(s1 (s1 + s1) + s1) = fl(3 s1)可能是舍入的,并不完全等于3个整数。(注意,fl(≥≥2)= fl(≥≥2)总是等于2,再次忽略溢出,因为这只是调整指数的问题。)

添加第四项所产生的舍入误差会抵消添加第三项所产生的舍入误差!

最新更新