Python 中的浮点数转换为分数
Float to Fraction conversion in Python
在Python3.52做float类型到Fraction类型转换的题目时,我发现了两种不同转换方式的区别。
第一种方法是:
>>> from fractions import Fraction
>>> x = 1232.23
>>> f = Fraction(*x.as_integer_ratio())
>>> print(f)
2709702426188841/2199023255552 #Answer
第二种方法是:
>>> from fractions import Fraction
>>> x = 1232.23
>>> f = Fraction(str(x))
>>> print(f)
123223/100 #Answer
我想知道这两个不同答案背后的原因?抱歉,如果这是一个愚蠢的问题,我是编程新手并且 Python.
已编辑:我找到了一种方法,可以将第一种方法获得的不准确分数转换为 limit_denominator
方法获得的准确分数:
>>> from fractions import Fraction
>>> x = 1232.23
>>> f = Fraction(*x.as_integer_ratio())
>>> f = f.limit_denominator(100)
>>> print(f)
123223/100
这其实是一个很好的问题。不同结果背后的原因是 x
不是真正的 1232.23
因为 1232.23
没有精确的浮点表示,所以 1232.23
最接近的浮点表示的小数表示是 2709702426188841/2199023255552
,但是当您使用 str(1232.23)
时,它会将其视为精确值 1232.23
和 returns 数字的真实最佳小数表示形式。
又是因为浮点数不是以 base-10(十进制)存储,而是以 base-2(二进制)存储。
以 10 为底的有限长度数字可能是以 2 为底的重复小数。而且由于浮点数是固定大小,重复的小数点会被截断,从而导致不准确。
当您使用 as_integer_ratio
作为以 2 为基数的重复小数的数字时,由于以 10 为基数到 2 为基数的转换略有不准确,您会得到一个有点愚蠢的分数.如果将这两个数字相除,该值将非常接近您的原始数字。
例如,虽然 1/10 = 0.1 以 10 为基数并且不是循环小数,但它实际上是以 2 为基数的循环小数。就像 1/3 = 0.333... 以 10 为底。
>>> (0.1).as_integer_ratio()
(3602879701896397, 36028797018963968)
如果 Python 的输出是准确的,即使您在提示中只输入 0.1
,您也会看到类似 1.00000...01 的输出。但是 Python 隐藏了 在一般情况下你的这种不准确,导致混淆。
在Python3.52做float类型到Fraction类型转换的题目时,我发现了两种不同转换方式的区别。
第一种方法是:
>>> from fractions import Fraction
>>> x = 1232.23
>>> f = Fraction(*x.as_integer_ratio())
>>> print(f)
2709702426188841/2199023255552 #Answer
第二种方法是:
>>> from fractions import Fraction
>>> x = 1232.23
>>> f = Fraction(str(x))
>>> print(f)
123223/100 #Answer
我想知道这两个不同答案背后的原因?抱歉,如果这是一个愚蠢的问题,我是编程新手并且 Python.
已编辑:我找到了一种方法,可以将第一种方法获得的不准确分数转换为 limit_denominator
方法获得的准确分数:
>>> from fractions import Fraction
>>> x = 1232.23
>>> f = Fraction(*x.as_integer_ratio())
>>> f = f.limit_denominator(100)
>>> print(f)
123223/100
这其实是一个很好的问题。不同结果背后的原因是 x
不是真正的 1232.23
因为 1232.23
没有精确的浮点表示,所以 1232.23
最接近的浮点表示的小数表示是 2709702426188841/2199023255552
,但是当您使用 str(1232.23)
时,它会将其视为精确值 1232.23
和 returns 数字的真实最佳小数表示形式。
又是因为浮点数不是以 base-10(十进制)存储,而是以 base-2(二进制)存储。
以 10 为底的有限长度数字可能是以 2 为底的重复小数。而且由于浮点数是固定大小,重复的小数点会被截断,从而导致不准确。
当您使用 as_integer_ratio
作为以 2 为基数的重复小数的数字时,由于以 10 为基数到 2 为基数的转换略有不准确,您会得到一个有点愚蠢的分数.如果将这两个数字相除,该值将非常接近您的原始数字。
例如,虽然 1/10 = 0.1 以 10 为基数并且不是循环小数,但它实际上是以 2 为基数的循环小数。就像 1/3 = 0.333... 以 10 为底。
>>> (0.1).as_integer_ratio()
(3602879701896397, 36028797018963968)
如果 Python 的输出是准确的,即使您在提示中只输入 0.1
,您也会看到类似 1.00000...01 的输出。但是 Python 隐藏了 在一般情况下你的这种不准确,导致混淆。