跳轉到內容

Python 和 Ruby 中的數學/Python 中的分數

來自 Wikibooks,開放世界的開放書籍

分數模組的官方 Python 文件在此

將非整數的數字寫成分數可以追溯到埃及人和巴比倫人,早於小數的使用。只要分母不是 10 的冪,我們仍然經常使用分數,儘管它們可能被某種程度上隱藏起來。

  1. 如果我們說一個人的身高是 5 英尺 7 英寸,那麼他以英尺為單位的身高是(一英尺有十二英寸);
  2. 當我們說現在是早上 8:13 時,我們的意思是自午夜以來已經過去了正好小時(493 分鐘)。
  3. 當羅密歐抱怨他已經等了超過三刻鐘來等茱麗葉時,他正用分數表達他等待時間的長度……
  4. 機率通常以分數表示(通常是埃及分數),例如“我中彩票的機會是一千萬分之一”,或者“賠率是 5 比 1”。
  5. 統計資料也可以用分數表示:“每 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)

演算法

[編輯 | 編輯原始碼]

Farey 約簡

[編輯 | 編輯原始碼]

使用 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 函式,向上舍入到整數。因此

  1. 我們必須從 math 模組匯入此函式。
  2. ceil(1/f) 的結果是一個實數,而不是整數,因此我們不能直接在分數中使用它(Python 會報錯)。我們使用 int 將其轉換為整數。

最後,我們必須將最後一個埃及分數新增到列表中,以完成級數。

執行上面的指令碼,我們發現

華夏公益教科書