在 Python 中除以 3
Division by 3 in Python
我是 Python 的新手,在尝试使用运算符时,我遇到了这个:
>>> 7.0 / 3
2.3333333333333335
结果不应该是 2.3333333333333333 或者 2.3333333333333334。为什么要这样四舍五入?
此外,关于 Python 2.7 中的楼层划分,我的结果是:
>>> 5 / 2
2
>>> 5 // 2
2
>>> 5.0 / 2
2.5
>>> 5.0 // 2
2.0
所以我的观察是,即使在浮点数的情况下,底数除法 return 也是整数商,而正常除法 [=23=] 是十进制值。这是真的吗?
Your language isn't broken, it's doing floating point math. Computers can only natively store integers, so they need some way of representing decimal numbers. This representation comes with some degree of inaccuracy. That's why, more often than not, .1 + .2 != .3.
Shouldn't the result be 2.3333333333333333 or maybe 2.3333333333333334. Why is it rounding the number in such a way?
关键是数字被四舍五入了。
第一次舍入是除法运算的一部分,将数字舍入到最接近的双精度浮点值。这是二进制运算而不是十进制运算。
第二次四舍五入是将浮点数转换为十进制表示形式进行显示的一部分。 可能 以十进制表示任何二进制小数的精确值,但通常不希望这样做,因为在大多数应用程序中这样做只会导致许多数字的假精度。 Python 而是输出最短的十进制近似值,它将往返于正确的浮点值。
我们可以通过使用 Fraction 和 Decimal 类型更好地了解发生了什么,不像直接转换为字符串将浮点数转换为 Fraction 或 Decimal 将给出准确的值。我们还可以使用 Fraction 类型来确定我们计算中的错误。
>>> from fractions import Fraction
>>> from decimal import Decimal
>>> 7.0 / 3
2.3333333333333335
>>> Decimal(7.0 / 3)
Decimal('2.333333333333333481363069950020872056484222412109375')
>>> Fraction(7.0 / 3)
Fraction(5254199565265579, 2251799813685248)
>>> Fraction(7,3) - Fraction(7.0 / 3)
Fraction(-1, 6755399441055744)
通过 Decimal 类型的转换向我们展示了浮点数的精确值,并展示了通常由浮点值精确转换为十进制所产生的许多假精度数字。
转换成分数也很有趣,分母是2251799813685248相当于251。这是完全有道理的,双精度浮点数有 53 个有效位的尾数,我们需要其中两个作为结果的整数部分,剩下 51 个作为小数部分。
我们浮点计算的误差是1/6755399441055744或⅓ * 2-51。这个错误小于我们精度步长 2-51 的一半,因此答案确实正确地四舍五入为双精度浮点值。
我是 Python 的新手,在尝试使用运算符时,我遇到了这个:
>>> 7.0 / 3
2.3333333333333335
结果不应该是 2.3333333333333333 或者 2.3333333333333334。为什么要这样四舍五入?
此外,关于 Python 2.7 中的楼层划分,我的结果是:
>>> 5 / 2
2
>>> 5 // 2
2
>>> 5.0 / 2
2.5
>>> 5.0 // 2
2.0
所以我的观察是,即使在浮点数的情况下,底数除法 return 也是整数商,而正常除法 [=23=] 是十进制值。这是真的吗?
Your language isn't broken, it's doing floating point math. Computers can only natively store integers, so they need some way of representing decimal numbers. This representation comes with some degree of inaccuracy. That's why, more often than not, .1 + .2 != .3.
Shouldn't the result be 2.3333333333333333 or maybe 2.3333333333333334. Why is it rounding the number in such a way?
关键是数字被四舍五入了。
第一次舍入是除法运算的一部分,将数字舍入到最接近的双精度浮点值。这是二进制运算而不是十进制运算。
第二次四舍五入是将浮点数转换为十进制表示形式进行显示的一部分。 可能 以十进制表示任何二进制小数的精确值,但通常不希望这样做,因为在大多数应用程序中这样做只会导致许多数字的假精度。 Python 而是输出最短的十进制近似值,它将往返于正确的浮点值。
我们可以通过使用 Fraction 和 Decimal 类型更好地了解发生了什么,不像直接转换为字符串将浮点数转换为 Fraction 或 Decimal 将给出准确的值。我们还可以使用 Fraction 类型来确定我们计算中的错误。
>>> from fractions import Fraction
>>> from decimal import Decimal
>>> 7.0 / 3
2.3333333333333335
>>> Decimal(7.0 / 3)
Decimal('2.333333333333333481363069950020872056484222412109375')
>>> Fraction(7.0 / 3)
Fraction(5254199565265579, 2251799813685248)
>>> Fraction(7,3) - Fraction(7.0 / 3)
Fraction(-1, 6755399441055744)
通过 Decimal 类型的转换向我们展示了浮点数的精确值,并展示了通常由浮点值精确转换为十进制所产生的许多假精度数字。
转换成分数也很有趣,分母是2251799813685248相当于251。这是完全有道理的,双精度浮点数有 53 个有效位的尾数,我们需要其中两个作为结果的整数部分,剩下 51 个作为小数部分。
我们浮点计算的误差是1/6755399441055744或⅓ * 2-51。这个错误小于我们精度步长 2-51 的一半,因此答案确实正确地四舍五入为双精度浮点值。