目錄

名稱

Math::BigInt::Lib - Math::BigInt 函式庫的虛擬父類別

語法

# In the backend library for Math::BigInt et al.

package Math::BigInt::MyBackend;

use Math::BigInt::Lib;
our @ISA = qw< Math::BigInt::Lib >;

sub _new { ... }
sub _str { ... }
sub _add { ... }
str _sub { ... }
...

# In your main program.

use Math::BigInt lib => 'MyBackend';

說明

此模組提供對大整數計算的支援。它並非用於直接使用,而是作為 Math::BigInt、Math::BigFloat、Math::BigRat 和相關模組所使用的後端函式庫的父類別。

其他後端函式庫包括 Math::BigInt::Calc、Math::BigInt::FastCalc、Math::BigInt::GMP 和 Math::BigInt::Pari。

為了允許使用多個大整數函式庫,Math::BigInt 已重新編寫,以使用外掛程式函式庫作為核心數學例程。任何符合 API 的模組都可以透過在您的程式中使用此方式來使用 Math::BigInt

use Math::BigInt lib => 'libname';

'libname' 是長名稱,例如 'Math::BigInt::Pari',或僅為簡短版本,例如 'Pari'。

一般注意事項

函式庫僅需要處理無符號大整數。輸入參數有效性的測試是由呼叫者執行的,因此無需擔心下溢 (例如,在 _sub()_dec() 中) 或零除 (例如,在 _div()_mod() 中) 或類似情況。

有些函式庫使用不修改其參數的方法,而有些函式庫甚至不使用物件,而是使用未祝福的參照。因此,函式庫方法總是作為類別方法呼叫,而不是實例方法

$x = Class -> method($x, $y);     # like this
$x = $x -> method($y);            # not like this ...
$x -> method($y);                 # ... or like this

以及布林方法

$bool = Class -> method($x, $y);  # like this
$bool = $x -> method($y);         # not like this

傳回值總是物件、字串、Perl 標量,或比較常式的 true/false。

API 版本

CLASS->api_version()

此方法不再使用,可以省略。未由子類別實作的方法將從此類別繼承。

建構函式

以下方法是強制性的:_new()、_str()、_add() 和 _sub()。但是,沒有 _mul() 和 _div(),計算會非常慢。

CLASS->_new(STR)

將表示無符號十進制數字的字串轉換為表示相同數字的物件。輸入已正規化,即與 ^(0|[1-9]\d*)$ 相符。

CLASS->_zero()

傳回表示數字零的物件。

CLASS->_one()

傳回表示數字一的物件。

CLASS->_two()

傳回表示數字二的物件。

CLASS->_ten()

傳回表示數字十的物件。

CLASS->_from_bin(STR)

傳回給定表示二進制數字的字串的物件。輸入有一個 '0b' 前置詞,並與正規表示法 ^0[bB](0|1[01]*)$ 相符。

CLASS->_from_oct(STR)

傳回給定表示八進制數字的字串的物件。輸入有一個 '0' 前置詞,並與正規表示法 ^0[1-7]*$ 相符。

CLASS->_from_hex(STR)

傳回給定表示十六進制數字的字串的物件。輸入有一個 '0x' 前置詞,並與正規表示法 ^0x(0|[1-9a-fA-F][\da-fA-F]*)$ 相符。

CLASS->_from_bytes(STR)

傳回給定表示數字的位元組字串的物件。位元組字串是大端序位元組順序,因此二位元組輸入字串 "\x01\x00" 應給出表示數字 256 的輸出值。

CLASS->_from_base(STR, BASE, COLLSEQ)

傳回給定字串 STR、基底 BASE 和校對順序 COLLSEQ 的物件。STR 中的每個字元都表示與字元在 COLLSEQ 中的位置相同的數值。STR 中的所有字元都必須存在於 COLLSEQ 中。

如果 BASE 小於或等於 94,且未指定校對序列,則使用下列預設校對序列。它包含所有 94 個可列印的 ASCII 字元,空白/空格除外

0123456789                  # ASCII  48 to  57
ABCDEFGHIJKLMNOPQRSTUVWXYZ  # ASCII  65 to  90
abcdefghijklmnopqrstuvwxyz  # ASCII  97 to 122
!"#$%&'()*+,-./             # ASCII  33 to  47
:;<=>?@                     # ASCII  58 to  64
[\]^_`                      # ASCII  91 to  96
{|}~                        # ASCII 123 to 126

如果使用預設校對序列,且 BASE 小於或等於 36,則會忽略 STR 中的字母大小寫。

例如,在 base 3 和校對序列 "-/|" 中,字元 "-" 代表 0,"/" 代表 1,"|" 代表 2。因此,如果 STR 為 "/|-,輸出為 1 * 3**2 + 2 * 3**1 + 0 * 3**0 = 15。

下列範例顯示標準的二進位、八進位、十進位和十六進位轉換。所有範例都傳回 250。

$x = $class -> _from_base("11111010", 2)
$x = $class -> _from_base("372", 8)
$x = $class -> _from_base("250", 10)
$x = $class -> _from_base("FA", 16)

更多範例,全部傳回 250

$x = $class -> _from_base("100021", 3)
$x = $class -> _from_base("3322", 4)
$x = $class -> _from_base("2000", 5)
$x = $class -> _from_base("caaa", 5, "abcde")
$x = $class -> _from_base("42", 62)
$x = $class -> _from_base("2!", 94)
CLASS->_from_base_num(ARRAY, BASE)

提供一個值陣列和一個基底,傳回一個物件。此方法等同於 _from_base(),但作用於陣列中的數字,而非字串中的字元。與 _from_base() 不同,所有輸入值都可以任意大。

$x = $class -> _from_base_num([1, 1, 0, 1], 2)    # $x is 13
$x = $class -> _from_base_num([3, 125, 39], 128)  # $x is 65191

數學函數

CLASS->_add(OBJ1, OBJ2)

加法。傳回將 OBJ2 加到 OBJ1 的結果。

CLASS->_mul(OBJ1, OBJ2)

乘法。傳回將 OBJ2 和 OBJ1 相乘的結果。

CLASS->_div(OBJ1, OBJ2)

除法。在純量環境中,傳回將 OBJ1 除以 OBJ2 並將結果截斷為整數後的商。在清單環境中,傳回商和餘數。

CLASS->_sub(OBJ1, OBJ2, FLAG)
CLASS->_sub(OBJ1, OBJ2)

減法。傳回將 OBJ2 減去 OBJ1 的結果。如果 flag 為 false 或省略,OBJ1 可能會被修改。如果 flag 為 true,OBJ2 可能會被修改。

CLASS->_sadd(OBJ1, SIGN1, OBJ2, SIGN2)

帶正負號的加法。傳回將帶有正負號 SIGN2 的 OBJ2 加到帶有正負號 SIGN1 的 OBJ1 的結果。

($obj3, $sign3) = $class -> _sadd($obj1, $sign1, $obj2, $sign2);
CLASS->_ssub(OBJ1, SIGN1, OBJ2, SIGN2)

帶正負號的減法。傳回將帶有正負號 SIGN2 的 OBJ2 減去帶有正負號 SIGN1 的 OBJ1 的結果。

($obj3, $sign3) = $class -> _sadd($obj1, $sign1, $obj2, $sign2);
CLASS->_dec(OBJ)

傳回將 OBJ 減一後的結果。

CLASS->_inc(OBJ)

傳回將 OBJ 加一後的結果。

CLASS->_mod(OBJ1, OBJ2)

傳回 OBJ1 除以 OBJ2 的餘數,也就是 OBJ1 除以 OBJ2 後的餘數。

CLASS->_sqrt(OBJ)

傳回 OBJ 的平方根,並取整數。

CLASS->_root(OBJ, N)

傳回 OBJ 的 N 次方根,並取整數。

CLASS->_fac(OBJ)

傳回 OBJ 的階乘,也就是將 OBJ 以下的所有正整數相乘的結果。

CLASS->_dfac(OBJ)

傳回 OBJ 的雙階乘。如果 OBJ 是偶數,傳回 OBJ 以下的所有正偶數相乘的結果,也就是 2*4*6*...*OBJ。如果 OBJ 是奇數,傳回所有正奇數相乘的結果,也就是 1*3*5*...*OBJ。

CLASS->_pow(OBJ1, OBJ2)

傳回 OBJ1 乘方 OBJ2 的結果。依慣例,0**0 = 1。

CLASS->_modinv(OBJ1, OBJ2)

傳回模反元素,也就是傳回 OBJ3,使得

(OBJ3 * OBJ1) % OBJ2 = 1 % OBJ2

結果傳回兩個參數。如果模反元素不存在,兩個參數都是未定義。否則,參數是一個數字(物件)和它的正負號(「+」或「-」)。

輸出值,加上它的正負號,必須是 1,2,...,OBJ2-1 範圍內的正值,或這個值減去 OBJ2。例如,如果輸入參數是代表數字 7 和 5 的物件,這個方法必須傳回代表數字 3 和「+」號的物件,因為 (3*7) % 5 = 1 % 5,或傳回代表數字 2 和「-」號的物件,因為 (-2*7) % 5 = 1 % 5。

CLASS->_modpow(OBJ1, OBJ2, OBJ3)

傳回模指數,也就是 (OBJ1 ** OBJ2) % OBJ3。

CLASS->_rsft(OBJ, N, B)

傳回將 OBJ 在 B 進制中向右位移 N 位後的結果。這等於執行 B**N 的整數除法並捨棄餘數,但速度可能快很多。

例如,如果物件 $obj 代表十六進制數字 0xabcde,則 _rsft($obj, 2, 16) 傳回代表數字 0xabc 的物件。而「餘數」0xde 會被捨棄,不會傳回。

CLASS->_lsft(OBJ, N, B)

在底數 B 中將 OBJ 向左移位 N 位後傳回結果。這等於乘以 B**N,但速度可能快得多。

CLASS->_log_int(OBJ, B)

傳回 OBJ 以 BASE 為底的對數,並截斷為整數。此方法有兩個輸出引數,OBJECT 和 STATUS。STATUS 是 Perl 標量;若 OBJ 是精確結果,則為 1;若結果截斷後才得到 OBJ,則為 0;若不知道 OBJ 是否為精確結果,則為 undef。

CLASS->_gcd(OBJ1, OBJ2)

傳回 OBJ1 和 OBJ2 的最大公因數。

CLASS->_lcm(OBJ1, OBJ2)

傳回 OBJ1 和 OBJ2 的最小公倍數。

CLASS->_fib(OBJ)

在標量內容中,傳回第 n 個斐波那契數:_fib(0) 傳回 0,_fib(1) 傳回 1,_fib(2) 傳回 1,_fib(3) 傳回 2,依此類推。在清單內容中,傳回從 F(0) 到 F(n) 的斐波那契數:0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ...

CLASS->_lucas(OBJ)

在標量內容中,傳回第 n 個盧卡斯數:_lucas(0) 傳回 2,_lucas(1) 傳回 1,_lucas(2) 傳回 3,依此類推。在清單內容中,傳回從 L(0) 到 L(n) 的盧卡斯數:2, 1, 3, 4, 7, 11, 18, 29,47, 76, ...

位元運算子

CLASS->_and(OBJ1, OBJ2)

傳回位元 and。

CLASS->_or(OBJ1, OBJ2)

傳回位元 or。

CLASS->_xor(OBJ1, OBJ2)

傳回位元 exclusive or。

CLASS->_sand(OBJ1, OBJ2, SIGN1, SIGN2)

傳回位元 signed and。

CLASS->_sor(OBJ1, OBJ2, SIGN1, SIGN2)

傳回位元 signed or。

CLASS->_sxor(OBJ1, OBJ2, SIGN1, SIGN2)

傳回位元 signed exclusive or。

布林運算子

CLASS->_is_zero(OBJ)

如果 OBJ 為零,則傳回真值,否則傳回假值。

CLASS->_is_one(OBJ)

如果 OBJ 為一,則傳回真值,否則傳回假值。

CLASS->_is_two(OBJ)

如果 OBJ 為二,則傳回真值,否則傳回假值。

CLASS->_is_ten(OBJ)

如果 OBJ 為十,則傳回真值,否則傳回假值。

CLASS->_is_even(OBJ)

如果 OBJ 為偶數,則傳回真值,否則傳回假值。

CLASS->_is_odd(OBJ)

如果 OBJ 為偶數,則傳回真值,否則傳回假值。

CLASS->_acmp(OBJ1, OBJ2)

比較 OBJ1 和 OBJ2,如果 OBJ1 數值上小於、等於或大於 OBJ2,則分別傳回 -1、0 或 1。

字串轉換

CLASS->_str(OBJ)

傳回表示 OBJ 十進位表示法的字串。傳回的字串不應有前導零,也就是說,它應符合 ^(0|[1-9]\d*)$

CLASS->_to_bin(OBJ)

傳回 OBJ 的二進位字串表示法。

CLASS->_to_oct(OBJ)

傳回數字的八進位字串表示法。

CLASS->_to_hex(OBJ)

傳回數字的十六進位字串表示法。

CLASS->_to_bytes(OBJ)

傳回 OBJ 的位元組字串表示法。位元組字串採用大端序,因此如果 OBJ 表示數字 256,輸出應為兩位元組字串「\x01\x00」。

CLASS->_to_base(OBJ, BASE, COLLSEQ)

傳回 OBJ 在 BASE 底數和 COLLSEQ 校對序列中的字串表示法。

$val = $class -> _new("210");
$str = $class -> _to_base($val, 10, "xyz")  # $str is "zyx"

$val = $class -> _new("32");
$str = $class -> _to_base($val, 2, "-|")  # $str is "|-----"

有關更多資訊,請參閱 _from_base()。

CLASS->_to_base_num(OBJ, BASE)

將給定的數字轉換為給定的進位。此方法等同於 _to_base(),但會傳回陣列中的數字,而非字串中的字元。在輸出中,第一個元素是最顯著的。與 _to_base() 不同,所有輸入值都可以任意大。

$x = $class -> _to_base_num(13, 2)        # $x is [1, 1, 0, 1]
$x = $class -> _to_base_num(65191, 128)   # $x is [3, 125, 39]
CLASS->_as_bin(OBJ)

類似於 _to_bin(),但加上 '0b' 字首。

CLASS->_as_oct(OBJ)

類似於 _to_oct(),但加上 '0' 字首。

CLASS->_as_hex(OBJ)

類似於 _to_hex(),但加上 '0x' 字首。

CLASS->_as_bytes(OBJ)

這是 _to_bytes() 的別名。

數字轉換

CLASS->_num(OBJ)

傳回 Perl 標量數字,表示數字 OBJ 盡可能接近。由於 Perl 標量具有有限精度,因此傳回值可能不會與 OBJ 完全相同。

其他

CLASS->_copy(OBJ)

傳回真正的複製 OBJ。

CLASS->_len(OBJ)

傳回 OBJ 中十進位數字的數量。輸出是 Perl 標量。

CLASS->_zeros(OBJ)

傳回尾數十進位零的數量。輸出是 Perl 標量。數字零沒有尾數十進位零。

CLASS->_digit(OBJ, N)

傳回 OBJ 中第 N 個數字,作為 Perl 標量。N 是 Perl 標量,其中零表示最右邊(最不顯著)的數字,而負值則從左邊(最顯著的數字)開始計算。如果 $obj 表示數字 123,則

CLASS->_digit($obj,  0)     # returns 3
CLASS->_digit($obj,  1)     # returns 2
CLASS->_digit($obj,  2)     # returns 1
CLASS->_digit($obj, -1)     # returns 1
CLASS->_digitsum(OBJ)

傳回基數 10 數字的總和。

CLASS->_check(OBJ)

如果物件無效,則傳回 true,否則傳回 false。最好將 true 值設為描述物件問題的字串。這是一個檢查常式,用於測試物件內部狀態是否有損毀。

CLASS->_set(OBJ)

xxx

API 版本 2

下列方法需要 API 版本 2 或更高。

建構函數

CLASS->_1ex(N)

傳回一個物件,表示數字 10**N,其中 N >= 0 是 Perl 標量。

數學函數

CLASS->_nok(OBJ1, OBJ2)

傳回二項式係數 OBJ1 除以 OBJ1。

其他

CLASS->_alen(OBJ)

傳回物件的近似小數位數。輸出為 Perl 標量。

包裝您自己的

如果您想將自己最愛的大數字 C 函式庫移植到 Math::BigInt 介面,您可以將任何現有的模組作為粗略的準則。您真的應該將最新的 Math::BigInt 和 Math::BigFloat 測試套件與您的模組包裝在一起,並取代其中任何下列

use Math::BigInt;

使用這個

use Math::BigInt lib => 'yourlib';

這樣您就可以確保您的函式庫在 Math::BigInt 中真正 100% 運作。

錯誤

請將任何錯誤或功能要求回報至 bug-math-bigint at rt.cpan.org,或透過 https://rt.cpan.org/Ticket/Create.html?Queue=Math-BigInt 的網路介面(需要登入)。我們將會收到通知,然後當我進行變更時,您會自動收到錯誤進度的通知。

支援

您可以使用 perldoc 指令找到這個模組的說明文件。

perldoc Math::BigInt::Calc

您也可以在下列位置尋找資訊

授權

這個程式是自由軟體;您可以在與 Perl 相同的條款下重新散布或修改它。

作者

Peter John Acklam, <pjacklam@gmail.com>

程式碼和文件基於 Tels <nospam-abuse@bloodgate.com> 的 Math::BigInt::Calc 模組。

另請參閱

Math::BigIntMath::BigInt::CalcMath::BigInt::GMPMath::BigInt::FastCalcMath::BigInt::Pari