关于py3中的分数class
About Fraction class in py3
有没有办法在 float
的分数表示中找到小数点后 kth
位置的数字? k
最多 10^6
。
我尝试将 float(Fraction)
转换为 str
,它没有给我所需的精度。
您正在寻找 Python 中的 decimal
模块(开箱即用 Python)。
from decimal import *
division = 5 / 3
print(division) # 1.6666666666666667
getcontext().prec = 6
division = Decimal(5) / Decimal(3)
print(division) # 1.66667
你可以使用像decimal
这样的高精度浮点包来计算这个,但是如果你只需要一个数字那么有更有效的方法:我们可以在整个计算过程中使用不大于 1000
的整数在几分之一秒内计算 34/23
(例如)的万亿位(例如)。
这是一个简单的函数,它给出小数点后的第 k
个数字 p/q
:
def digit(p, q, k):
"""
Return the kth digit after the point (k >= 1)
of the fraction p / q. p, q and k should be integers.
"""
return pow(10, k-1, q) * p % q * 10 // q
还有一个例子:34/23 有十进制展开 1.4782608695652173913043478260869565217...
,所以让我们使用上面的函数从该展开中获取一些数字
>>> digit(34, 23, 1)
4
>>> digit(34, 23, 3)
8
>>> digit(34, 23, 20)
0
>>> digit(34, 23, 30)
6
>>> digit(34, 23, 1_000_000_000) # billionth digit after the point
5
下面以 34/23
为例解释了为什么会这样:假设我们想计算小数点后的第 5 位。下面是我们如何手动执行此操作:我们首先乘以 10**4
以将所需数字之前的位置移动到该点的左侧:
10**4 * 34 / 23 = 14782.608695652173913043478260869565217...
现在我们丢掉整数部分,只保留小数部分:
fractional part = 0.608695652173913043478260869565217...
然后我们乘以 10 得到小数点左边所需的数字:
10 * fractional part = 6.08695652173913043478260869565217...
最后我们丢掉结果的小数部分,只保留 6
,这是我们想要的数字。
所有这些操作在计算上都很容易高效地完成:10**(k-1) * p / q
的小数部分是 (10**(k-1) * p % q) / q
,我们可以在 Python 中使用三个有效地计算 10**(k-1)*p % q
pow
的参数形式为 pow(10, k-1, q) * p % q
。现在分子写成r
,我们要计算r * 10 / q
的整数部分。但这只是 r * 10 // q
,使用 Python 的整数除法运算符。
所以整个事情就变成了:
pow(10, k-1, q) * p % q * 10 // q
有没有办法在 float
的分数表示中找到小数点后 kth
位置的数字? k
最多 10^6
。
我尝试将 float(Fraction)
转换为 str
,它没有给我所需的精度。
您正在寻找 Python 中的 decimal
模块(开箱即用 Python)。
from decimal import *
division = 5 / 3
print(division) # 1.6666666666666667
getcontext().prec = 6
division = Decimal(5) / Decimal(3)
print(division) # 1.66667
你可以使用像decimal
这样的高精度浮点包来计算这个,但是如果你只需要一个数字那么有更有效的方法:我们可以在整个计算过程中使用不大于 1000
的整数在几分之一秒内计算 34/23
(例如)的万亿位(例如)。
这是一个简单的函数,它给出小数点后的第 k
个数字 p/q
:
def digit(p, q, k):
"""
Return the kth digit after the point (k >= 1)
of the fraction p / q. p, q and k should be integers.
"""
return pow(10, k-1, q) * p % q * 10 // q
还有一个例子:34/23 有十进制展开 1.4782608695652173913043478260869565217...
,所以让我们使用上面的函数从该展开中获取一些数字
>>> digit(34, 23, 1)
4
>>> digit(34, 23, 3)
8
>>> digit(34, 23, 20)
0
>>> digit(34, 23, 30)
6
>>> digit(34, 23, 1_000_000_000) # billionth digit after the point
5
下面以 34/23
为例解释了为什么会这样:假设我们想计算小数点后的第 5 位。下面是我们如何手动执行此操作:我们首先乘以 10**4
以将所需数字之前的位置移动到该点的左侧:
10**4 * 34 / 23 = 14782.608695652173913043478260869565217...
现在我们丢掉整数部分,只保留小数部分:
fractional part = 0.608695652173913043478260869565217...
然后我们乘以 10 得到小数点左边所需的数字:
10 * fractional part = 6.08695652173913043478260869565217...
最后我们丢掉结果的小数部分,只保留 6
,这是我们想要的数字。
所有这些操作在计算上都很容易高效地完成:10**(k-1) * p / q
的小数部分是 (10**(k-1) * p % q) / q
,我们可以在 Python 中使用三个有效地计算 10**(k-1)*p % q
pow
的参数形式为 pow(10, k-1, q) * p % q
。现在分子写成r
,我们要计算r * 10 / q
的整数部分。但这只是 r * 10 // q
,使用 Python 的整数除法运算符。
所以整个事情就变成了:
pow(10, k-1, q) * p % q * 10 // q