简体   繁体   English

python 中的浮点运算

[英]float point arithmetic in python

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

The above is an output from python interpreter. 以上是来自 python 解释器的 output。 I understand the fact that 我明白这样一个事实
floating point arithmetic is done using base 2 and is stored as binary in the 浮点运算使用基数 2 完成,并以二进制形式存储在
and so the difference in calculations like above results. 所以计算上的差异就像上面的结果一样。
Now I found that.4 =.011(0011) [The number inside () repeats infinitely this is a binary 现在发现.4 =.011(0011) [()里面的数字无限重复这是一个二进制
representation of this fraction] since this cannot be stored exactly an approximate value 这个分数的表示] 因为这不能精确地存储一个近似值
will be stored. 将被存储。
Similary 0.3 =.01(0011) 相似度 0.3 =.01(0011)
So both 0.4 and 0.3 cannot be stored exactly internally. 所以 0.4 和 0.3 都不能在内部完全存储。
But then what's the reason for python to return first as True and the second as False 但是,python 首先返回 True 而第二个返回 False 的原因是什么
As both cannot be compared 因为两者无法比较
_______________________________________________________________________________ _______________________________________________________________________________
I did some research and found the following: 我做了一些研究,发现以下内容:
 >>> 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')

This probably explains why the additions are happening the way they are这可能解释了为什么添加会以它们的方式发生
assuming that Decimal is giving the exact ouput of the number stored underneath假设 Decimal 给出了存储在下面的数字的确切输出

But then what's the reason for python to return first as True and the second as False As both cannot be compared但是那么 python 首先返回 True 而第二个返回 False 的原因是什么因为两者都无法比较

Floating-point numbers absolutely can be compared for equality.浮点数绝对可以比较是否相等。 Problems arise only when you expect exact equality to be preserved by an approximate computation .只有当您期望通过近似计算来保持精确相等时,才会出现问题。 But the semantics of floating-point equality comparison is perfectly well defined.但是浮点相等比较的语义是完美定义的。

When you write 0.1 in a program, this is rounded to the nearest IEEE 754 binary64 floating-point number, which is the real number 0.1000000000000000055511151231257827021181583404541015625, or 0x1.999999999999ap−4 in hexadecimal notation (the 'p−4' part means × 2⁻⁴).当您在程序中写入0.1时,它会四舍五入为最接近的 IEEE 754 binary64 浮点数,即实数 0.100000000000000005551115123125782702118158340454101-5625,或 0x1.999999999999ap-4 的十六进制表示法中的“×2”部分⁴)。 Every (normal) binary64 floating-point number is a real number of the form ±2ⁿ × (1 + /2⁵³), where and are integers with −1022 ≤ ≤ 1023 and 0 ≤ < 2⁵³;每个(正常)二进制 64 浮点数都是 ±2ⁿ × (1 + /2⁵³) 形式的实数,其中 和 是整数,−1022 ≤ ≤ 1023 和 0 ≤ < 2⁵³; this one is the nearest such number to 0.1.这是最接近 0.1 的数字。

When you add that to itself three times in floating-point arithmetic, the exact result 0.3000000000000000166533453693773481063544750213623046875 is rounded to 0.3000000000000000444089209850062616169452667236328125 or 0x1.3333333333334p−2 (since there are only 53 bits of precision available), but when you write 0.3 , you get 0.299999999999999988897769753748434595763683319091796875 or 0x1.3333333333333p−2 which is slightly closer to 0.3. When you add that to itself three times in floating-point arithmetic, the exact result 0.3000000000000000166533453693773481063544750213623046875 is rounded to 0.3000000000000000444089209850062616169452667236328125 or 0x1.3333333333334p−2 (since there are only 53 bits of precision available), but when you write 0.3 , you get 0.299999999999999988897769753748434595763683319091796875 or 0x1.3333333333333p-2 稍微接近 0.3。

However, four times 0.1000000000000000055511151231257827021181583404541015625 or 0x1.999999999999ap−4 is 0.4000000000000000222044604925031308084726333618164062500 or 0x1.999999999999ap−2, which is also the closest floating-point number to 0.4 and hence is what you get when you write 0.4 in a program. However, four times 0.1000000000000000055511151231257827021181583404541015625 or 0x1.999999999999ap−4 is 0.4000000000000000222044604925031308084726333618164062500 or 0x1.999999999999ap−2, which is also the closest floating-point number to 0.4 and hence is what you get when you write 0.4 in a program. So when you write 4*0.1 , the result is exactly the same floating-point number as when you write 0.4 .因此,当您编写4*0.1时,结果与您编写0.4的浮点数完全相同

Now, you didn't write 4*0.1 —instead you wrote .1 +.1 +.1 +.1 .现在,你没有写4*0.1 ——而是你写了.1 +.1 +.1 +.1 But it turns out there is a theorem in binary floating-point arithmetic that x + x + x + x —that is, fl(fl(fl( + ) + ) + )—always yields exactly 4 without rounding (except when it overflows), in spite of the fact that x + x + x or fl(fl( + ) + ) = fl(3) may be rounded and not exactly equal to 3. (Note that fl( + ) = fl(2) is always equal to 2, again ignoring overflow, because it's just a matter of adjusting the exponent.)但事实证明,在二进制浮点算术中存在一个定理,即x + x + x + x x——即 fl(fl(fl( + ) + ) + )——在不四舍五入的情况下总是准确地得出 4(除非它溢出),尽管x + x + x或 fl(fl( + ) + ) = fl(3) 可能被四舍五入并且不完全等于 3。(请注意,fl( + ) = fl(2) 是总是等于 2,再次忽略溢出,因为这只是调整指数的问题。)

It just happens that any rounding error committed by adding the fourth term cancels out whatever rounding error may have been committed by adding the third!恰好通过添加第四项所犯的任何舍入错误抵消了添加第三项可能已提交的任何舍入错误!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM