內容

名稱

bigrat - Perl 的透明大有理數支援

語法

use bigrat;

print 2 + 4.5;                      # Math::BigRat 13/2
print 1/3 + 1/4;                    # Math::BigRat 7/12
print inf + 42;                     # Math::BigRat inf
print NaN * 7;                      # Math::BigRat NaN
print hex("0x1234567890123490");    # Perl v5.10.0 or later

{
    no bigrat;
    print 1/3;                      # 0.33333...
}

# for older Perls, import into current package:
use bigrat qw/hex oct/;
print hex("0x1234567890123490");
print oct("01234567890123490");

說明

在給定範圍內的所有數字文字都會轉換為 Math::BigRat 物件。

除了範圍運算子 .. 以外,所有運算子(包括基本數學運算)都會被覆寫。

所以,以下程式碼

use bigrat;
$x = 1234;

會建立一個 Math::BigRat 並將其參考儲存在 $x 中。這會在透明且不為人知的情況下發生。

你可以透過以下程式碼看到

perl -Mbigrat -le 'print ref(1234)'

由於數字實際上是物件,因此你可以對它們呼叫 Math::BigRat 中所有常用的方法。這甚至可以在某種程度上對運算式運作

perl -Mbigrat -le '$x = 1234; print $x->bdec()'
perl -Mbigrat -le 'print 1234->copy()->binc();'
perl -Mbigrat -le 'print 1234->copy()->binc->badd(6);'
perl -Mbigrat -le 'print +(1234)->copy()->binc()'

(請注意,如果運算式以 '(' 開頭,則 print 無法執行預期功能,因此需要 +

你甚至可以像往常一樣將運算鏈結在一起

perl -Mbigrat -le 'print 1234->copy()->binc->badd(6);'
1241

請注意,以下程式碼無法如預期執行(不會印出任何內容),因為 Perl(v5.8.0 版)目前還無法覆寫 '..'

perl -Mbigrat -le 'for (1..2) { print ref($_); }'

選項

bigrat 識別一些選項,這些選項可以在透過 use 載入時傳遞。以下為現有的選項

a 或準確度

這會設定所有數學運算的準確度。參數必須大於或等於零。有關詳細資訊,請參閱 Math::BigInt 的 bround() 方法。

perl -Mbigrat=a,50 -le 'print sqrt(20)'

請注意,同時設定精度和準確度是不可能的。

p 或 precision

這會為所有數學運算設定精度。引數可以是任何整數。負值表示小數點後固定的位數,而正值則會捨入到小數點左邊的這個位數。0 表示捨入為整數。請參閱 Math::BigInt 的 bfround() 方法以取得詳細資料。

perl -Mbigrat=p,-50 -le 'print sqrt(20)'

請注意,同時設定精度和準確度是不可能的。

t 或 trace

這會啟用追蹤模式,主要是用於除錯。

l、lib、try 或 only

載入不同的數學函式庫,請參閱 "數學函式庫"

perl -Mbigrat=l,GMP -e 'print 2 ** 512'
perl -Mbigrat=lib,GMP -e 'print 2 ** 512'
perl -Mbigrat=try,GMP -e 'print 2 ** 512'
perl -Mbigrat=only,GMP -e 'print 2 ** 512'
hex

使用可以處理大數的版本覆寫內建的 hex() 方法。這會透過將其匯出到目前的套件來覆寫它。在 Perl v5.10.0 及更新版本中,這不是那麼必要,因為只要 bigrat 實用程式碼處於作用中,hex() 就會在目前的範圍中以字彙方式覆寫。

oct

使用可以處理大數的版本覆寫內建的 oct() 方法。這會透過將其匯出到目前的套件來覆寫它。在 Perl v5.10.0 及更新版本中,這不是那麼必要,因為只要 bigrat 實用程式碼處於作用中,oct() 就會在目前的範圍中以字彙方式覆寫。

v 或 version

這會印出模組的名稱和版本,然後結束。

perl -Mbigrat=v

數學函式庫

使用數字的數學運算(預設)是由後端函式庫模組 Math::BigInt::Calc 執行。預設值等同於說

use bigrat lib => 'Calc';

你可以使用以下方式變更它

use bigrat lib => 'GMP';

以下會先嘗試尋找 Math::BigInt::Foo,然後是 Math::BigInt::Bar,如果這也失敗,則會回復到 Math::BigInt::Calc

use bigrat lib => 'Foo,Math::BigInt::Bar';

如果找不到指定的任何函式庫,則使用 c<lib> 會發出警告,而 Math::BigInt 會退回到其中一個預設函式庫。若要抑制此警告,請改用 c<try>

use bigrat try => 'GMP';

如果你希望程式碼中斷,而不是退回,請改用 only

use bigrat only => 'GMP';

請參閱各模組文件以取得更多詳細資料。

方法呼叫

由於所有數字現在都是物件,因此您可以使用 Math::BigRat API 中的所有方法。

但請注意。當使用以下方式複製數字時,只會進行淺層複製。

$x = 9; $y = $x;
$x = $y = 7;

使用複製或原始值與超載數學運算無妨,例如,以下運算會執行

$x = 9; $y = $x;
print $x + 1, " ", $y,"\n";     # prints 10 9

但呼叫任何會直接修改數字的方法,將會導致同時毀損原始值和複製值

$x = 9; $y = $x;
print $x->badd(1), " ", $y,"\n";        # prints 10 10

$x = 9; $y = $x;
print $x->binc(1), " ", $y,"\n";        # prints 10 10

$x = 9; $y = $x;
print $x->bmul(2), " ", $y,"\n";        # prints 18 18

使用不會修改,但會測試內容的方法

$x = 9; $y = $x;
$z = 9 if $x->is_zero();                # works fine

請參閱複製建構函式和超載中的 =,以及 Math::BigFloat 中的文件,以取得進一步的詳細資料。

方法

inf()

返回 Math::BigRat->binf() 的捷徑。很有用,因為 Perl 不總是能正確處理裸字 inf

NaN()

返回 Math::BigRat->bnan() 的捷徑。很有用,因為 Perl 不總是能正確處理裸字 NaN

e
# perl -Mbigrat=e -wle 'print e'

傳回歐拉數 e,又稱 exp(1)。

PI
# perl -Mbigrat=PI -wle 'print PI'

傳回 PI。

bexp()
bexp($power, $accuracy);

傳回歐拉數 e 提升到適當次方,達到所需的精度。

範例

# perl -Mbigrat=bexp -wle 'print bexp(1,80)'
bpi()
bpi($accuracy);

傳回 PI,達到所需的精度。

範例

# perl -Mbigrat=bpi -wle 'print bpi(80)'
accuracy()

設定或取得精度。

precision()

設定或取得精度。

round_mode()

設定或取得捨入模式。

div_scale()

設定或取得除法比例。

in_effect()
use bigrat;

print "in effect\n" if bigrat::in_effect;       # true
{
    no bigrat;
    print "in effect\n" if bigrat::in_effect;   # false
}

如果 bigrat 在目前範圍內有效,則傳回 true 或 false。

此方法僅適用於 Perl v5.9.4 或更新版本。

注意事項

十六進制、八進制和二進制浮點數字面量

Perl(和此模組)接受十六進制、八進制和二進制浮點數字面量,但對於 v5.32.0 之前的 Perl 版本,請小心使用,因為某些 Perl 版本會在不提示的情況下給出錯誤的結果。

運算子與字面量重載

bigrat 透過重載整數和浮點數字面量的處理方式來運作,將它們轉換為 Math::BigRat 物件。

這表示僅包含字串值或字串字面量的算術運算會使用 Perl 內建的運算子來執行。

例如

use bigrat;
my $x = "900000000000000009";
my $y = "900000000000000007";
print $x - $y;

在預設的 32 位元組建中輸出 0,因為 bigrat 從未看到字串字面量。若要確保表達式全部視為 Math::BigRat 物件,請在表達式中使用數字字面量

print +(0+$x) - $y;
範圍

Perl 不允許重載範圍,因此您既不能安全地將範圍與 bigrat 端點一起使用,也不能將迭代器變數設為 Math::BigRat

use 5.010;
for my $i (12..13) {
  for my $j (20..21) {
    say $i ** $j;  # produces a floating-point number,
                   # not an object
  }
}
in_effect()

此方法僅適用於 Perl v5.9.4 或更新版本。

hex()/oct()

bigrat 使用可以處理大整數值的其他版本來覆寫這些常式。然而,在 Perl 5.9.4 之前的版本中,除非您特別使用兩個匯入標籤「hex」和「oct」來要求,否則不會發生這種情況 - 然後它將會是全域性的,且無法在使用 no bigrat 的範圍內停用

use bigrat qw/hex oct/;

print hex("0x1234567890123456");
{
    no bigrat;
    print hex("0x1234567890123456");
}

第二次呼叫 hex() 會警告非可移植常數。

將其與下列內容進行比較

use bigrat;

# will warn only under Perl older than v5.9.4
print hex("0x1234567890123456");

範例

perl -Mbigrat -le 'print sqrt(33)'
perl -Mbigrat -le 'print 2**255'
perl -Mbigrat -le 'print 4.5+2**255'
perl -Mbigrat -le 'print 3/7 + 5/7 + 8/3'
perl -Mbigrat -le 'print 12->is_odd()';
perl -Mbigrat=l,GMP -le 'print 7 ** 7777'

錯誤

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

支援

您可以使用 perldoc 指令尋找此模組的文件。

perldoc bigrat

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

授權

此程式為自由軟體;您可以在與 Perl 相同的條款下重新散佈或修改它。

另請參閱

bignumbigint

Math::BigIntMath::BigFloatMath::BigRatMath::Big,以及 Math::BigInt::FastCalcMath::BigInt::PariMath::BigInt::GMP

作者