Python 和 Ruby 中的数学/Python 中的分数
分数模块的官方 Python 文档在此。
将非整数的数字写成分数可以追溯到埃及人和巴比伦人,早于小数的使用。只要分母不是 10 的幂,我们仍然经常使用分数,尽管它们可能被某种程度上隐藏起来。
- 如果我们说一个人的身高是 5 英尺 7 英寸,那么他以英尺为单位的身高是(一英尺有十二英寸);
- 当我们说现在是早上 8:13 时,我们的意思是自午夜以来已经过去了正好小时(493 分钟)。
- 当罗密欧抱怨他已经等了超过三刻钟来等茱丽叶时,他正用分数表达他等待时间的长度……
- 概率通常以分数表示(通常是埃及分数),例如“我中彩票的机会是一千万分之一”,或者“赔率是 5 比 1”。
- 统计数据也可以用分数表示:“每 6 个人中有 5 个人穿毛衣”。
方程 0.2+0.5=0.7 可以写成,但方程无法使用十进制数字精确地写出来。Python 将 1/2+1/3 的结果给出为 0.8333333333333333;尽管所有数字都存在,但这并不是精确的答案。
对于分数的精确计算,Python 有一个fractions
模块。要使用本章中的脚本,请从以下行开始
from fractions import *
这将从分数模块导入所有内容。
在Python中输入分数,使用Fraction(n,d)
,记住要从fractions模块导入它。
from fractions import *
a = Fraction(24,10)
print(a) # 12/5
我们发现 Python 在实例化时自动简化了分数。
如果将 0 作为分母输入,则分数将不会创建,并且会出现错误消息。我们不能将数字除以 0。
from fractions import *
a = Fraction(24,10)
print(a.numerator)
print(a.denominator)
当然,的分子在简化后不再是 24。
要获取分数的值(它的分子除以它的分母),我们可以将其转换为“浮点数”——这指的是计算机通常如何存储非整数的数字(作为“浮点数”)。
from fractions import *
a = Fraction(24,10)
print(float(a))
我们也可以将实数转换为分数,但如果该数字是不能在二进制中精确表示的数字,则结果可能会令人惊讶。
from fractions import *
a = Fraction.from_float(1.2)
print(a)
而不是,我们得到分数。这是因为不能在二进制中精确存储,就像不能精确地写成小数一样。在这种情况下,我们可以通过直接从小数到分数,而无需计算机将其转换为二进制来获得更好的结果。
from fractions import *
a = Fraction('1.2')
print(a)
分数的运算写法与其他数字相同,但结果通常是分数。
要取分数的反,在其前面加上-
符号。例如
from fractions import *
a = Fraction(2,-3)
print(-a)
要找到分数的倒数,用 1 除以它。
from fractions import *
a = Fraction(5,4)
print(1/a)
两个分数的和是一个分数。
from fractions import *
a = Fraction(34,21)
b = Fraction(21,13)
print(a+b)
两个分数的差是一个分数。
from fractions import *
a = Fraction(34,21)
b = Fraction(21,13)
print(a-b)
两个分数的积是一个分数。
from fractions import *
a = Fraction(34,21)
b = Fraction(21,13)
print(a*b)
两个分数的商是一个分数(只要第二个分数不为零)。
from fractions import *
a = Fraction(34,21)
b = Fraction(21,13)
print(a/b)
from fractions import *
a = Fraction(32,7)
b = Fraction(7,2)
print(a%b)
如果指数是整数,则分数的幂是一个分数。
from fractions import *
a = Fraction(3,2)
print(a**12)
print(a**(-1))
但如果指数是实数,则分数的幂是一个实数。
from fractions import *
a = Fraction(9,4)
print(a**0.5)
使用 Python 的 fractions
模块可以轻松创建Farey 序列。
from fractions import *
def Farey(a,b):
n = a.numerator+b.numerator
d = a.denominator+b.denominator
return Fraction(n,d)
a = Fraction(3,4)
b = Fraction(1,13)
print(Farey(a,b))
这可以用来生成Stern-Brocot 树;这可能不会解释太多,但它在数学中有所应用。
埃及分数由一系列整数的倒数组成;埃及人以不使用分子而闻名。任何分数都可以写成埃及分数的和,我们可以使用斐波那契算法为任何分数找到这样的和。在下面的 Python 示例中,该算法生成一个分数列表,所有分数的分子都为 1,这些分数加起来等于给定的分数 f。由于 f 可能大于 1,因此我们从一个整数开始列表。
from fractions import *
from math import ceil
def egypt(f):
e = int(f)
f -= e
parts = [e]
while(f.numerator>1):
e = Fraction(1, int(ceil(1/f)))
parts.append(e)
f -= e
parts.append(f)
return parts
a = Fraction(21,13)
print(egypt(a)) # [1, Fraction(1, 2), Fraction(1, 9), Fraction(1, 234)]
print(sum(egypt(a)) # 21/13 (confirming that these fractions add up to the original value)
上面代码的一些解释:每个埃及分数的分母应该是一个整数,并且大于分数 f 的倒数,以便算法收敛。一种解决方案是将倒数向下舍入到整数(使用 int
)并加 1。但是,如果 f 的倒数是整数,则加 1 会导致一个无限级数。因此,我们使用 ceil
函数,向上舍入到整数。因此
- 我们必须从
math
模块导入此函数。 ceil(1/f)
的结果是一个实数,而不是整数,因此我们不能直接在分数中使用它(Python 会报错)。我们使用int
将其转换为整数。
最后,我们必须将最后一个埃及分数添加到列表中,以完成级数。
运行上面的脚本,我们发现。