Math::BigInt - 任意大小整數數學套件
use Math::BigInt;
# or make it faster with huge numbers: install (optional)
# Math::BigInt::GMP and always use (it falls back to
# pure Perl if the GMP library is not installed):
# (See also the L<MATH LIBRARY> section!)
# to warn if Math::BigInt::GMP cannot be found, use
use Math::BigInt lib => 'GMP';
# to suppress the warning if Math::BigInt::GMP cannot be found, use
# use Math::BigInt try => 'GMP';
# to die if Math::BigInt::GMP cannot be found, use
# use Math::BigInt only => 'GMP';
# Configuration methods (may be used as class methods and instance methods)
Math::BigInt->accuracy(); # get class accuracy
Math::BigInt->accuracy($n); # set class accuracy
Math::BigInt->precision(); # get class precision
Math::BigInt->precision($n); # set class precision
Math::BigInt->round_mode(); # get class rounding mode
Math::BigInt->round_mode($m); # set global round mode, must be one of
# 'even', 'odd', '+inf', '-inf', 'zero',
# 'trunc', or 'common'
Math::BigInt->config(); # return hash with configuration
# Constructor methods (when the class methods below are used as instance
# methods, the value is assigned the invocand)
$x = Math::BigInt->new($str); # defaults to 0
$x = Math::BigInt->new('0x123'); # from hexadecimal
$x = Math::BigInt->new('0b101'); # from binary
$x = Math::BigInt->from_hex('cafe'); # from hexadecimal
$x = Math::BigInt->from_oct('377'); # from octal
$x = Math::BigInt->from_bin('1101'); # from binary
$x = Math::BigInt->from_base('why', 36); # from any base
$x = Math::BigInt->from_base_num([1, 0], 2); # from any base
$x = Math::BigInt->bzero(); # create a +0
$x = Math::BigInt->bone(); # create a +1
$x = Math::BigInt->bone('-'); # create a -1
$x = Math::BigInt->binf(); # create a +inf
$x = Math::BigInt->binf('-'); # create a -inf
$x = Math::BigInt->bnan(); # create a Not-A-Number
$x = Math::BigInt->bpi(); # returns pi
$y = $x->copy(); # make a copy (unlike $y = $x)
$y = $x->as_int(); # return as a Math::BigInt
$y = $x->as_float(); # return as a Math::BigFloat
$y = $x->as_rat(); # return as a Math::BigRat
# Boolean methods (these don't modify the invocand)
$x->is_zero(); # if $x is 0
$x->is_one(); # if $x is +1
$x->is_one("+"); # ditto
$x->is_one("-"); # if $x is -1
$x->is_inf(); # if $x is +inf or -inf
$x->is_inf("+"); # if $x is +inf
$x->is_inf("-"); # if $x is -inf
$x->is_nan(); # if $x is NaN
$x->is_positive(); # if $x > 0
$x->is_pos(); # ditto
$x->is_negative(); # if $x < 0
$x->is_neg(); # ditto
$x->is_odd(); # if $x is odd
$x->is_even(); # if $x is even
$x->is_int(); # if $x is an integer
# Comparison methods
$x->bcmp($y); # compare numbers (undef, < 0, == 0, > 0)
$x->bacmp($y); # compare absolutely (undef, < 0, == 0, > 0)
$x->beq($y); # true if and only if $x == $y
$x->bne($y); # true if and only if $x != $y
$x->blt($y); # true if and only if $x < $y
$x->ble($y); # true if and only if $x <= $y
$x->bgt($y); # true if and only if $x > $y
$x->bge($y); # true if and only if $x >= $y
# Arithmetic methods
$x->bneg(); # negation
$x->babs(); # absolute value
$x->bsgn(); # sign function (-1, 0, 1, or NaN)
$x->bnorm(); # normalize (no-op)
$x->binc(); # increment $x by 1
$x->bdec(); # decrement $x by 1
$x->badd($y); # addition (add $y to $x)
$x->bsub($y); # subtraction (subtract $y from $x)
$x->bmul($y); # multiplication (multiply $x by $y)
$x->bmuladd($y,$z); # $x = $x * $y + $z
$x->bdiv($y); # division (floored), set $x to quotient
# return (quo,rem) or quo if scalar
$x->btdiv($y); # division (truncated), set $x to quotient
# return (quo,rem) or quo if scalar
$x->bmod($y); # modulus (x % y)
$x->btmod($y); # modulus (truncated)
$x->bmodinv($mod); # modular multiplicative inverse
$x->bmodpow($y,$mod); # modular exponentiation (($x ** $y) % $mod)
$x->bpow($y); # power of arguments (x ** y)
$x->blog(); # logarithm of $x to base e (Euler's number)
$x->blog($base); # logarithm of $x to base $base (e.g., base 2)
$x->bexp(); # calculate e ** $x where e is Euler's number
$x->bnok($y); # x over y (binomial coefficient n over k)
$x->buparrow($n, $y); # Knuth's up-arrow notation
$x->backermann($y); # the Ackermann function
$x->bsin(); # sine
$x->bcos(); # cosine
$x->batan(); # inverse tangent
$x->batan2($y); # two-argument inverse tangent
$x->bsqrt(); # calculate square root
$x->broot($y); # $y'th root of $x (e.g. $y == 3 => cubic root)
$x->bfac(); # factorial of $x (1*2*3*4*..$x)
$x->bdfac(); # double factorial of $x ($x*($x-2)*($x-4)*...)
$x->btfac(); # triple factorial of $x ($x*($x-3)*($x-6)*...)
$x->bmfac($k); # $k'th multi-factorial of $x ($x*($x-$k)*...)
$x->blsft($n); # left shift $n places in base 2
$x->blsft($n,$b); # left shift $n places in base $b
# returns (quo,rem) or quo (scalar context)
$x->brsft($n); # right shift $n places in base 2
$x->brsft($n,$b); # right shift $n places in base $b
# returns (quo,rem) or quo (scalar context)
# Bitwise methods
$x->band($y); # bitwise and
$x->bior($y); # bitwise inclusive or
$x->bxor($y); # bitwise exclusive or
$x->bnot(); # bitwise not (two's complement)
# Rounding methods
$x->round($A,$P,$mode); # round to accuracy or precision using
# rounding mode $mode
$x->bround($n); # accuracy: preserve $n digits
$x->bfround($n); # $n > 0: round to $nth digit left of dec. point
# $n < 0: round to $nth digit right of dec. point
$x->bfloor(); # round towards minus infinity
$x->bceil(); # round towards plus infinity
$x->bint(); # round towards zero
# Other mathematical methods
$x->bgcd($y); # greatest common divisor
$x->blcm($y); # least common multiple
# Object property methods (do not modify the invocand)
$x->sign(); # the sign, either +, - or NaN
$x->digit($n); # the nth digit, counting from the right
$x->digit(-$n); # the nth digit, counting from the left
$x->length(); # return number of digits in number
($xl,$f) = $x->length(); # length of number and length of fraction
# part, latter is always 0 digits long
# for Math::BigInt objects
$x->mantissa(); # return (signed) mantissa as a Math::BigInt
$x->exponent(); # return exponent as a Math::BigInt
$x->parts(); # return (mantissa,exponent) as a Math::BigInt
$x->sparts(); # mantissa and exponent (as integers)
$x->nparts(); # mantissa and exponent (normalised)
$x->eparts(); # mantissa and exponent (engineering notation)
$x->dparts(); # integer and fraction part
$x->fparts(); # numerator and denominator
$x->numerator(); # numerator
$x->denominator(); # denominator
# Conversion methods (do not modify the invocand)
$x->bstr(); # decimal notation, possibly zero padded
$x->bsstr(); # string in scientific notation with integers
$x->bnstr(); # string in normalized notation
$x->bestr(); # string in engineering notation
$x->bfstr(); # string in fractional notation
$x->to_hex(); # as signed hexadecimal string
$x->to_bin(); # as signed binary string
$x->to_oct(); # as signed octal string
$x->to_bytes(); # as byte string
$x->to_base($b); # as string in any base
$x->to_base_num($b); # as array of integers in any base
$x->as_hex(); # as signed hexadecimal string with prefixed 0x
$x->as_bin(); # as signed binary string with prefixed 0b
$x->as_oct(); # as signed octal string with prefixed 0
# Other conversion methods
$x->numify(); # return as scalar (might overflow or underflow)
Math::BigInt 提供支援任意精度的整數。也為 Perl 運算子提供重載。
這些常式的輸入值可以是任何看起來像數字且表示整數的純量數字或字串。Perl 接受為文字數字常數的任何內容都應被此模組接受,但有限的非整數會傳回 NaN。
忽略前導和尾隨空白。
忽略前導零,但二進制指數的浮點數除外,這種情況下數字會被解釋為八進制浮點數。例如,「01.4p+0」會給出 1.5,「00.4p+0」會給出 0.5,但「0.4p+0」會給出 NaN。而「0377」會給出 255,「0377p0」會給出 255。
如果字串有「0x」或「0X」前綴,會被解釋為十六進制數字。
如果字串有「0o」或「0O」前綴,會被解釋為八進制數字。有「0」前綴的浮點數文字也會被解釋為八進制數字。
如果字串有「0b」或「0B」前綴,會被解釋為二進制數字。
底線字元被允許的方式與在文字數字常數中被允許的方式相同。
如果字串無法被解釋,或不表示有限整數,會傳回 NaN。
對於十六進制、八進制和二進制浮點數,指數必須用字母「p」或「P」與有效數字(尾數)分開,而不是像十進制數字一樣用「e」或「E」分開。
有效字串輸入的一些範例
Input string Resulting value
123 123
1.23e2 123
12300e-2 123
67_538_754 67538754
-4_5_6.7_8_9e+0_1_0 -4567890000000
0x13a 314
0x13ap0 314
0x1.3ap+8 314
0x0.00013ap+24 314
0x13a000p-12 314
0o472 314
0o1.164p+8 314
0o0.0001164p+20 314
0o1164000p-10 314
0472 472 Note!
01.164p+8 314
00.0001164p+20 314
01164000p-10 314
0b100111010 314
0b1.0011101p+8 314
0b0.00010011101p+12 314
0b100111010000p-3 314
以純量數字給出的輸入可能會失去精度。加上引號以確保不會遺失任何數字
$x = Math::BigInt->new( 56789012345678901234 ); # bad
$x = Math::BigInt->new('56789012345678901234'); # good
目前,Math::BigInt-
new()>(沒有輸入引數)和 Math::BigInt-
new("")> 會傳回 0。這可能會在未來變更,因此務必始終使用下列明確形式來取得零
$zero = Math::BigInt->bzero();
輸出值通常是 Math::BigInt 物件。
布林運算子 is_zero()
、is_one()
、is_inf()
等會傳回 true 或 false。
比較運算子 bcmp()
和 bacmp()
) 會傳回 -1、0、1 或 undef。
以下各方法(config()、accuracy() 和 precision() 除外)接受三個額外參數。這些參數 $A
、$P
和 $R
分別是 accuracy
、precision
和 round_mode
。請參閱 "ACCURACY and PRECISION" 部分,以取得更多資訊。
設定類別變數會影響之後建立的所有物件實例。
Math::BigInt->accuracy(5); # set class accuracy
$x->accuracy(5); # set instance accuracy
$A = Math::BigInt->accuracy(); # get class accuracy
$A = $x->accuracy(); # get instance accuracy
設定或取得準確度,亦即有效數字的數量。準確度必須是整數。如果準確度設定為 undef
,則不會進行捨入。
或者,可以使用 "round()"、"bround()" 或 "bfround()" 之一,或透過將所需準確度傳遞給方法作為額外參數,來明確捨入結果
my $x = Math::BigInt->new(30000);
my $y = Math::BigInt->new(7);
print scalar $x->copy()->bdiv($y, 2); # prints 4300
print scalar $x->copy()->bdiv($y)->bround(2); # prints 4300
請參閱 "ACCURACY and PRECISION" 部分,以取得更多詳細資料。
$y = Math::BigInt->new(1234567); # $y is not rounded
Math::BigInt->accuracy(4); # set class accuracy to 4
$x = Math::BigInt->new(1234567); # $x is rounded automatically
print "$x $y"; # prints "1235000 1234567"
print $x->accuracy(); # prints "4"
print $y->accuracy(); # also prints "4", since
# class accuracy is 4
Math::BigInt->accuracy(5); # set class accuracy to 5
print $x->accuracy(); # prints "4", since instance
# accuracy is 4
print $y->accuracy(); # prints "5", since no instance
# accuracy, and class accuracy is 5
注意:每個類別都有自己的全域變數,與 Math::BigInt 分開,但可以對 Math::BigInt 進行子類別化,並將子類別的全域變數設為 Math::BigInt 的別名。
Math::BigInt->precision(-2); # set class precision
$x->precision(-2); # set instance precision
$P = Math::BigInt->precision(); # get class precision
$P = $x->precision(); # get instance precision
設定或取得精度,亦即相對於小數點的捨入位置。精度必須是整數。將精度設定為 $P 表示每個數字會根據捨入模式向上或向下捨入到最接近的 10**$P 倍數。如果精度設定為 undef
,則不會進行捨入。
您可能想要改用 "accuracy()"。使用 "accuracy()" 可以設定每個結果應有的數字數量,使用 "precision()" 可以設定捨入位置。
請參閱 "ACCURACY and PRECISION" 部分,以取得更多詳細資料。
$y = Math::BigInt->new(1234567); # $y is not rounded
Math::BigInt->precision(4); # set class precision to 4
$x = Math::BigInt->new(1234567); # $x is rounded automatically
print $x; # prints "1230000"
注意:每個類別都有自己的全域變數,與 Math::BigInt 分開,但可以對 Math::BigInt 進行子類別化,並將子類別的全域變數設為 Math::BigInt 的別名。
設定/取得備用準確度。這是當準確度和精度都沒有明確設定時所使用的準確度。當運算可能嘗試傳回無限數位時,會使用此準確度。
設定/取得捨入模式。
設定/取得用於升級的類別。當運算可能導致非整數時,運算元會升級到此類別。例如,bignum 會使用此類別。預設值為 undef
,亦即不進行升級。
# with no upgrading
$x = Math::BigInt->new(12);
$y = Math::BigInt->new(5);
print $x / $y, "\n"; # 2 as a Math::BigInt
# with upgrading to Math::BigFloat
Math::BigInt -> upgrade("Math::BigFloat");
print $x / $y, "\n"; # 2.4 as a Math::BigFloat
# with upgrading to Math::BigRat (after loading Math::BigRat)
Math::BigInt -> upgrade("Math::BigRat");
print $x / $y, "\n"; # 12/5 as a Math::BigRat
設定/取得降級類別。預設為 undef
,即不降級。Math::BigInt 不會執行降級。
$x->modify('bpowd');
如果物件可以使用指定的運算修改,此方法會傳回 0;如果不行,則傳回 1。
例如,Math::BigInt::Constant 會使用此方法。
Math::BigInt->config("trap_nan" => 1); # set
$accu = Math::BigInt->config("accuracy"); # get
設定或取得類別變數。唯讀參數標示為 RO。可讀寫參數標示為 RW。支援下列參數。
Parameter RO/RW Description
Example
============================================================
lib RO Name of the math backend library
Math::BigInt::Calc
lib_version RO Version of the math backend library
0.30
class RO The class of config you just called
Math::BigRat
version RO version number of the class you used
0.10
upgrade RW To which class numbers are upgraded
undef
downgrade RW To which class numbers are downgraded
undef
precision RW Global precision
undef
accuracy RW Global accuracy
undef
round_mode RW Global round mode
even
div_scale RW Fallback accuracy for division etc.
40
trap_nan RW Trap NaNs
undef
trap_inf RW Trap +inf/-inf
undef
$x = Math::BigInt->new($str,$A,$P,$R);
從純量或另一個 Math::BigInt 物件建立新的 Math::BigInt 物件。輸入接受十進位、十六進位(開頭為 '0x')、八進位(開頭為 ('0o') 或二進位(開頭為 '0b')。
請參閱 "輸入" 以取得更多關於可接受輸入格式的資訊。
$x = Math::BigInt->from_dec("314159"); # input is decimal
將輸入解釋為十進位。它等同於 new(),但只接受表示有限十進位數字的字串。
$x = Math::BigInt->from_hex("0xcafe"); # input is hexadecimal
將輸入解釋為十六進位字串。前綴 "0x" 或 "x" 為選用。如果存在前綴,可以在前綴後或任何兩個數字之間放置一個底線字元。如果輸入無效,則傳回 NaN。
$x = Math::BigInt->from_oct("0775"); # input is octal
將輸入解釋為八進位字串,並傳回對應的值。前綴 "0"(零)為選用。如果存在前綴,可以在前綴後或任何兩個數字之間放置一個底線字元。如果輸入無效,則傳回 NaN。
$x = Math::BigInt->from_bin("0b10011"); # input is binary
將輸入解釋為二進位字串。前綴 "0b" 或 "b" 為選用。如果存在前綴,可以在前綴後或任何兩個數字之間放置一個底線字元。如果輸入無效,則傳回 NaN。
$x = Math::BigInt->from_bytes("\xf3\x6b"); # $x = 62315
將輸入解釋為位元組字串,假設為大端位元組順序。輸出永遠是非負有限整數。
在某些特殊情況下,from_bytes() 會符合 unpack() 執行的轉換
$b = "\x4e"; # one char byte string
$x = Math::BigInt->from_bytes($b); # = 78
$y = unpack "C", $b; # ditto, but scalar
$b = "\xf3\x6b"; # two char byte string
$x = Math::BigInt->from_bytes($b); # = 62315
$y = unpack "S>", $b; # ditto, but scalar
$b = "\x2d\xe0\x49\xad"; # four char byte string
$x = Math::BigInt->from_bytes($b); # = 769673645
$y = unpack "L>", $b; # ditto, but scalar
$b = "\x2d\xe0\x49\xad\x2d\xe0\x49\xad"; # eight char byte string
$x = Math::BigInt->from_bytes($b); # = 3305723134637787565
$y = unpack "Q>", $b; # ditto, but scalar
給定字串、基底和選用的排序序列,將字串解釋為指定基底的數字。排序序列描述字串中每個字元的數值。
如果未提供排序序列,則會使用預設排序序列。如果基底小於或等於 36,則排序序列為包含 36 個字元 "0" 到 "9" 和 "A" 到 "Z" 的字串。在此情況下,會忽略輸入中的字母大小寫。如果基底大於 36,且小於或等於 62,則排序序列為包含 62 個字元 "0" 到 "9"、"A" 到 "Z" 和 "a" 到 "z" 的字串。大於 62 的基底需要明確指定排序序列。
以下範例顯示標準二進位、八進位和十六進位轉換。所有情況都傳回 250。
$x = Math::BigInt->from_base("11111010", 2);
$x = Math::BigInt->from_base("372", 8);
$x = Math::BigInt->from_base("fa", 16);
當基底小於或等於 36,且未提供排序序列時,會忽略字母大小寫,因此以下兩個範例也會傳回 250
$x = Math::BigInt->from_base("6Y", 16);
$x = Math::BigInt->from_base("6y", 16);
當基數大於 36,且未給定校對順序時,預設校對順序包含大小寫字母,因此輸入中的字母大小寫不會被忽略
$x = Math::BigInt->from_base("6S", 37); # $x is 250
$x = Math::BigInt->from_base("6s", 37); # $x is 276
$x = Math::BigInt->from_base("121", 3); # $x is 16
$x = Math::BigInt->from_base("XYZ", 36); # $x is 44027
$x = Math::BigInt->from_base("Why", 42); # $x is 58314
校對順序可以是任何一組唯一字元。這兩個案例是等效的
$x = Math::BigInt->from_base("100", 2, "01"); # $x is 4
$x = Math::BigInt->from_base("|--", 2, "-|"); # $x is 4
傳回一個新的 Math::BigInt 物件,給定一個值陣列和一個基數。此方法等同於 from_base()
,但處理陣列中的數字,而非字串中的字元。與 from_base()
不同,所有輸入值都可以任意大。
$x = Math::BigInt->from_base_num([1, 1, 0, 1], 2) # $x is 13
$x = Math::BigInt->from_base_num([3, 125, 39], 128) # $x is 65191
$x = Math::BigInt->bzero();
$x->bzero();
傳回一個新的 Math::BigInt 物件,表示零。如果用作執行個體方法,會將值指定給呼叫者。
$x = Math::BigInt->bone(); # +1
$x = Math::BigInt->bone("+"); # +1
$x = Math::BigInt->bone("-"); # -1
$x->bone(); # +1
$x->bone("+"); # +1
$x->bone('-'); # -1
建立一個新的 Math::BigInt 物件,表示一。選用引數為「-」或「+」,表示您要正一或負一。如果用作執行個體方法,會將值指定給呼叫者。
$x = Math::BigInt->binf($sign);
建立一個新的 Math::BigInt 物件,表示無限大。選用引數為「-」或「+」,表示您要正無限大或負無限大。如果用作執行個體方法,會將值指定給呼叫者。
$x->binf();
$x->binf('-');
$x = Math::BigInt->bnan();
建立一個新的 Math::BigInt 物件,表示 NaN(非數字)。如果用作執行個體方法,會將值指定給呼叫者。
$x->bnan();
$x = Math::BigInt->bpi(100); # 3
$x->bpi(100); # 3
建立一個新的 Math::BigInt 物件,表示 PI。如果用作執行個體方法,會將值指定給呼叫者。使用 Math::BigInt,這總是傳回 3。
如果升級生效,會傳回 PI,四捨五入到 N 位數,並使用目前的捨入模式
use Math::BigFloat;
use Math::BigInt upgrade => "Math::BigFloat";
print Math::BigInt->bpi(3), "\n"; # 3.14
print Math::BigInt->bpi(100), "\n"; # 3.1415....
$x->copy(); # make a true copy of $x (unlike $y = $x)
當 Math::BigInt 遇到它不知道如何處理的物件時,會呼叫這些方法。例如,假設 $x 是 Math::BigInt 或其子類別,且 $y 已定義,但不是 Math::BigInt 或其子類別。如果您執行
$x -> badd($y);
$y 需要轉換為 $x 可以處理的物件。首先檢查 $y 是否為 $x 可以升級的物件。如果是,則不再進行其他嘗試。接下來檢查 $y 是否支援方法 as_int()
。如果支援,則呼叫 as_int()
,如果不支援,則檢查 $y 是否支援方法 as_number()
。如果支援,則呼叫 as_number()
。預期方法 as_int()
(和 as_number()
)會傳回一個與 $x 相同類別的物件、其子類別,或 ref($x)->new()
可以解析來建立物件的字串。
as_number()
是 as_int()
的別名。as_number
在 v1.22 中引入,而 as_int()
在 v1.68 中引入。
在 Math::BigInt 中,as_int()
的效果與 copy()
相同。
將引數傳回為 Math::BigFloat 物件。
將引數傳回為 Math::BigRat 物件。
這些方法都不會修改呼叫物件。
$x->is_zero(); # true if $x is 0
如果呼叫物件為零,則傳回 true,否則傳回 false。
$x->is_one(); # true if $x is +1
$x->is_one("+"); # ditto
$x->is_one("-"); # true if $x is -1
如果呼叫物件為一,則傳回 true,否則傳回 false。
$x->is_finite(); # true if $x is not +inf, -inf or NaN
如果呼叫物件為有限數字(即不是 +inf、-inf 或 NaN),則傳回 true。
$x->is_inf(); # true if $x is +inf
$x->is_inf("+"); # ditto
$x->is_inf("-"); # true if $x is -inf
如果呼叫物件為無限大,則傳回 true,否則傳回 false。
$x->is_nan(); # true if $x is NaN
$x->is_positive(); # true if > 0
$x->is_pos(); # ditto
如果呼叫物件為正數,則傳回 true,否則傳回 false。NaN
不是正數也不是負數。
$x->is_negative(); # true if < 0
$x->is_neg(); # ditto
如果呼叫物件為負數,則傳回 true,否則傳回 false。NaN
不是正數也不是負數。
$x->is_non_positive(); # true if <= 0
如果呼叫物件為負數或零,則傳回 true。
$x->is_non_negative(); # true if >= 0
如果呼叫物件為正數或零,則傳回 true。
$x->is_odd(); # true if odd, false for even
如果呼叫物件為奇數,則傳回 true,否則傳回 false。NaN
、+inf
和 -inf
不是奇數也不是偶數。
$x->is_even(); # true if $x is even
如果呼叫函數為偶數,則傳回 true,否則傳回 false。NaN
、+inf
、-inf
不是整數,也不是奇數或偶數。
$x->is_int(); # true if $x is an integer
如果呼叫函數為整數,則傳回 true,否則傳回 false。NaN
、+inf
、-inf
不是整數。
這些方法都不會修改呼叫函數物件。請注意,NaN
不會小於、大於或等於任何其他值,即使是 NaN
也不例外。
$x->bcmp($y);
根據 $x 是否小於、等於或大於 $y,傳回 -1、0、1。如果任何運算元為 NaN,則傳回未定義。
$x->bacmp($y);
根據 $x 的絕對值是否小於、等於或大於 $y 的絕對值,傳回 -1、0、1。如果任何運算元為 NaN,則傳回未定義。
$x -> beq($y);
僅當 $x 等於 $y 時傳回 true,否則傳回 false。
$x -> bne($y);
僅當 $x 不等於 $y 時傳回 true,否則傳回 false。
$x -> blt($y);
僅當 $x 等於 $y 時傳回 true,否則傳回 false。
$x -> ble($y);
僅當 $x 小於或等於 $y 時傳回 true,否則傳回 false。
$x -> bgt($y);
僅當 $x 大於 $y 時傳回 true,否則傳回 false。
$x -> bge($y);
僅當 $x 大於或等於 $y 時傳回 true,否則傳回 false。
這些方法會修改呼叫函數物件並傳回它。
$x->bneg();
對數字取負,例如在「+」和「-」之間或在「+inf」和「-inf」之間變更符號。對 NaN 或零不執行任何動作。
$x->babs();
將數字設為其絕對值,例如將符號從「-」變更為「+」,並將符號從「-inf」變更為「+inf」。對 NaN 或正數不執行任何動作。
$x->bsgn();
符號函數。根據數字是負數、零或正數,將數字設定為 -1、0 或 1。不會修改 NaN。
$x->bnorm(); # normalize (no-op)
標準化數字。這是一個空操作,僅為向後相容性而提供。
$x->binc(); # increment x by 1
$x->bdec(); # decrement x by 1
$x->badd($y); # addition (add $y to $x)
$x->bsub($y); # subtraction (subtract $y from $x)
$x->bmul($y); # multiplication (multiply $x by $y)
$x->bmuladd($y,$z);
將 $x 乘以 $y,然後將 $z 加到結果中,
此方法已在 Math::BigInt 的 v1.87(2007 年 6 月)中新增。
$x->bdiv($y); # divide, set $x to quotient
透過進行取整除法(F 除法)將 $x 除以 $y,其中商數是兩個運算元的取整(朝負無窮大捨入)商數。在列表內容中,傳回商數和餘數。餘數為零或與第二個運算元同號。在純量內容中,只傳回商數。
商數永遠是兩個運算元實值商數小於或等於的最大整數,而餘數(當它非零時)永遠與第二個運算元同號;因此,例如,
1 / 4 => ( 0, 1)
1 / -4 => (-1, -3)
-3 / 4 => (-1, 1)
-3 / -4 => ( 0, -3)
-11 / 2 => (-5, 1)
11 / -2 => (-5, -1)
重載運算子 % 的行為與 Perl 內建 % 運算子的行為一致(如 perlop 手冊頁所述),且等式
$x == ($x / $y) * $y + ($x % $y)
對任何有限 $x 和有限、非零 $y 成立。
Perl 的「use integer」可能會變更 % 和 / 對純量的行為。這是因為在「use integer」下,Perl 會執行底層 C 函式庫認為正確的動作,而這會有所不同。然而,「use integer」不會變更 Math::BigInt 物件的執行方式。
$x->btdiv($y); # divide, set $x to quotient
透過進行截斷除法(T 除法)將 $x 除以 $y,其中商數是兩個運算元的截斷(朝零捨入)商數。在列表內容中,傳回商數和餘數。餘數為零或與第一個運算元同號。在純量內容中,只傳回商數。
$x->bmod($y); # modulus (x % y)
傳回 $x 模 $y,亦即取整除法(F 除法)後的餘數。此方法類似 Perl 的 % 運算子。請參閱 "bdiv()"。
$x->btmod($y); # modulus
傳回截斷除法(T 除法)後的餘數。請參閱 "btdiv()"。
$x->bmodinv($mod); # modular multiplicative inverse
傳回 $x
對模數 $mod
的乘法反元素。如果
$y = $x -> copy() -> bmodinv($mod)
則 $y
是最接近於零且與 $mod
同號的數字,滿足
($x * $y) % $mod = 1 % $mod
如果 $x
和 $y
非零,它們必須是相對質數,也就是說 bgcd($y, $mod)==1
。如果不存在模乘法反元素,則傳回 'NaN
'。
$num->bmodpow($exp,$mod); # modular exponentiation
# ($num**$exp % $mod)
傳回 $num
對模數 $mod
取 $exp
次方的值,使用二進制指數運算。bmodpow
遠比寫
$num ** $exp % $mod
好得多,因為它快很多 - 它會在可能的情況下將內部變數化簡為模數,因此它作用於較小的數字。
bmodpow
也支援負指數。
bmodpow($num, -1, $mod)
與
bmodinv($num, $mod)
$x->bpow($y); # power of arguments (x ** y)
完全相等。bpow()
(和捨入函數)現在會修改第一個引數並傳回它,這與舊程式碼不同,舊程式碼會保留第一個引數不變,只傳回結果。這是為了與 badd()
等函數保持一致。前三個會修改 $x,最後一個不會
print bpow($x,$i),"\n"; # modify $x
print $x->bpow($i),"\n"; # ditto
print $x **= $i,"\n"; # the same
print $x ** $i,"\n"; # leave $x alone
不過,$x **= $y
這個形式比 $x = $x ** $y;
快。
$x->blog($base, $accuracy); # logarithm of x to the base $base
如果沒有定義 $base
,則使用歐拉數 (e)
print $x->blog(undef, 100); # log(x) to 100 digits
$x->bexp($accuracy); # calculate e ** X
計算表達式 e ** $x
,其中 e
是歐拉數。
這個方法在 Math::BigInt 的 v1.82(2007 年 4 月)中新增。
另請參閱 "blog()"。
$x->bnok($y); # x over y (binomial coefficient n over k)
計算 n 選 k 的二項式係數,也稱為「組合」函數,也就是
( n ) n!
| | = --------
( k ) k!(n-k)!
其中 n 和 k 為非負整數。這個方法實作了完整的 Kronenburg 延伸(Kronenburg, M.J. "The Binomial Coefficient for Negative Arguments." 18 May 2011. http://arxiv.org/abs/1105.3689/),以下的偽程式碼說明了這個延伸
if n >= 0 and k >= 0:
return binomial(n, k)
if k >= 0:
return (-1)^k*binomial(-n+k-1, k)
if k <= n:
return (-1)^(n-k)*binomial(-k-1, n-k)
else
return 0
此行為與 Maple 和 Mathematica 函數對負整數 n、k 的行為相同。
$a -> buparrow($n, $b); # modifies $a
$x = $a -> uparrow($n, $b); # does not modify $a
這個方法實作了 Knuth 的上箭符號表示法,其中 $n 是表示上箭符號數量的非負整數。$n = 0 表示乘法,$n = 1 表示指數運算,$n = 2 表示冪運算,$n = 3 表示超冪運算,依此類推。以下說明了 $n$ 的前幾個值之間的關係。
請參閱 https://en.wikipedia.org/wiki/Knuth%27s_up-arrow_notation。
$m -> backermann($n); # modifies $a
$x = $m -> ackermann($n); # does not modify $a
此方法實作 Ackermann 函數
/ n + 1 if m = 0
A(m, n) = | A(m-1, 1) if m > 0 and n = 0
\ A(m-1, A(m, n-1)) if m > 0 and n > 0
它的值會快速增長,即使對於小的輸入值。例如,A(4, 2) 是個有 19729 個小數位元的整數。
請參閱 https://en.wikipedia.org/wiki/Ackermann_function
my $x = Math::BigInt->new(1);
print $x->bsin(100), "\n";
計算 $x 的正弦值,並修改 $x 的值。
在 Math::BigInt 中,除非升級生效,否則結果會被截斷為整數。
此方法已在 Math::BigInt 的 v1.87(2007 年 6 月)中新增。
my $x = Math::BigInt->new(1);
print $x->bcos(100), "\n";
計算 $x 的餘弦值,並修改 $x 的值。
在 Math::BigInt 中,除非升級生效,否則結果會被截斷為整數。
此方法已在 Math::BigInt 的 v1.87(2007 年 6 月)中新增。
my $x = Math::BigFloat->new(0.5);
print $x->batan(100), "\n";
計算 $x 的反正切值,並修改 $x 的值。
在 Math::BigInt 中,除非升級生效,否則結果會被截斷為整數。
此方法已在 Math::BigInt 的 v1.87(2007 年 6 月)中新增。
my $x = Math::BigInt->new(1);
my $y = Math::BigInt->new(1);
print $y->batan2($x), "\n";
計算 $y
除以 $x
的反正切值,並修改 $y 的值。
在 Math::BigInt 中,除非升級生效,否則結果會被截斷為整數。
此方法已在 Math::BigInt 的 v1.87(2007 年 6 月)中新增。
$x->bsqrt(); # calculate square root
bsqrt()
傳回截斷為整數的平方根。
如果您想要平方根的更佳近似值,請使用
$x = Math::BigFloat->new(12);
Math::BigFloat->precision(0);
Math::BigFloat->round_mode('even');
print $x->copy->bsqrt(),"\n"; # 4
Math::BigFloat->precision(2);
print $x->bsqrt(),"\n"; # 3.46
print $x->bsqrt(3),"\n"; # 3.464
$x->broot($N);
計算 $x
的 N 次方根。
$x->bfac(); # factorial of $x
傳回 $x
的階乘,亦即 $x*($x-1)*($x-2)*...*2*1,也就是包含 $x
在內的正整數的乘積。$x
必須大於 -1。當使用多階乘表示法時,N 的階乘通常寫成 N! 或 N!1。
$x->bdfac(); # double factorial of $x
傳回 $x
的雙階乘,亦即 $x*($x-2)*($x-4)*... $x
必須大於 -2。當使用多階乘表示法時,N 的雙階乘通常寫成 N!! 或 N!2。
$x->btfac(); # triple factorial of $x
傳回 $x
的三階乘,亦即 $x*($x-3)*($x-6)*... $x
必須大於 -3。當使用多階乘表示法時,N 的三階乘通常寫成 N!!! 或 N!3。
$x->bmfac($k); # $k'th multifactorial of $x
傳回 $x
的多階乘,亦即 $x*($x-$k)*($x-2*$k)*... $x
必須大於 -$k。當使用多階乘表示法時,N 的多階乘通常寫成 N!K。
$F = $n->bfib(); # a single Fibonacci number
@F = $n->bfib(); # a list of Fibonacci numbers
在標量環境中,傳回單一的費氏數列。在清單環境中,傳回費氏數列的清單。呼叫函數是輸出中的最後一個元素。
費氏數列定義如下
F(0) = 0
F(1) = 1
F(n) = F(n-1) + F(n-2)
在清單環境中,F(0) 和 F(n) 分別是輸出中的第一個和最後一個數字。例如,如果 $n 是 12,則 @F = $n->bfib()
會傳回下列值,F(0) 到 F(12)
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144
該數列也可以使用重新排列的遞迴關係式擴充到負索引 n
F(n-2) = F(n) - F(n-1)
提供雙向序列
n -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7
F(n) 13 -8 5 -3 2 -1 1 0 1 1 2 3 5 8 13
如果 $n 為 -12,則會傳回下列值,F(0) 至 F(12)
0, 1, -1, 2, -3, 5, -8, 13, -21, 34, -55, 89, -144
$F = $n->blucas(); # a single Lucas number
@F = $n->blucas(); # a list of Lucas numbers
在標量內容中,傳回單一 Lucas 數字。在清單內容中,傳回 Lucas 數字清單。呼叫函數為輸出中的最後一個元素。
Lucas 序列定義如下
L(0) = 2
L(1) = 1
L(n) = L(n-1) + L(n-2)
在清單內容中,L(0) 和 L(n) 分別為輸出中的第一個和最後一個數字。例如,如果 $n 為 12,則 @L = $n->blucas()
會傳回下列值,L(0) 至 L(12)
2, 1, 3, 4, 7, 11, 18, 29, 47, 76, 123, 199, 322
該數列也可以使用重新排列的遞迴關係式擴充到負索引 n
L(n-2) = L(n) - L(n-1)
提供雙向序列
n -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7
L(n) 29 -18 11 -7 4 -3 1 2 1 3 4 7 11 18 29
如果 $n 為 -12,則會傳回下列值,L(0) 至 L(-12)
2, 1, -3, 4, -7, 11, -18, 29, -47, 76, -123, 199, -322
$x->brsft($n); # right shift $n places in base 2
$x->brsft($n, $b); # right shift $n places in base $b
後者等於
$x -> bdiv($b -> copy() -> bpow($n))
$x->blsft($n); # left shift $n places in base 2
$x->blsft($n, $b); # left shift $n places in base $b
後者等於
$x -> bmul($b -> copy() -> bpow($n))
$x->band($y); # bitwise and
$x->bior($y); # bitwise inclusive or
$x->bxor($y); # bitwise exclusive or
$x->bnot(); # bitwise not (two's complement)
二補數(按位元非)。這等於下列方法,但速度較快
$x->binc()->bneg();
$x->round($A,$P,$round_mode);
使用捨入模式 $round_mode
將 $x 捨入至準確度 $A
或精度 $P
。
$x->bround($N); # accuracy: preserve $N digits
將 $x 捨入至 $N 位數的準確度。
$x->bfround($N);
捨入至 10**$N 的倍數。範例
Input N Result
123456.123456 3 123500
123456.123456 2 123450
123456.123456 -2 123456.12
123456.123456 -3 123456.123
$x->bfloor();
將 $x 朝向負無限大捨入,亦即將 $x 設為小於或等於 $x 的最大整數。
$x->bceil();
將 $x 朝向正無限大捨入,亦即將 $x 設為大於或等於 $x 的最小整數)。
$x->bint();
將 $x 朝向零捨入。
$x -> bgcd($y); # GCD of $x and $y
$x -> bgcd($y, $z, ...); # GCD of $x, $y, $z, ...
傳回最大公因數 (GCD)。
$x -> blcm($y); # LCM of $x and $y
$x -> blcm($y, $z, ...); # LCM of $x, $y, $z, ...
傳回最小公倍數 (LCM)。
$x->sign();
傳回 $x 的符號,意即 +
、-
、-inf
、+inf
或 NaN。
如果您希望 $x 具有特定符號,請使用下列方法之一
$x->babs(); # '+'
$x->babs()->bneg(); # '-'
$x->bnan(); # 'NaN'
$x->binf(); # '+inf'
$x->binf('-'); # '-inf'
$x->digit($n); # return the nth digit, counting from right
如果 $n
為負數,則從左邊開始計算位數。
$x->digitsum();
計算 10 進位數字的總和並傳回。
$x->bdigitsum();
計算 10 進位數字的總和並將結果指定給呼叫函數。
$x->length();
($xl, $fl) = $x->length();
傳回數字的十進位表示法中的數字個數。在清單內容中,傳回整數和小數部分的長度。對於 Math::BigInt 物件,小數部分的長度永遠是 0。
以下內容可能不會產生你預期的結果
$c = Math::BigInt->new(123);
print $c->length(),"\n"; # prints 30
它會列印數字中的數字個數和小數部分中的數字個數,因為 print 會在清單內容中呼叫 length()
。請使用類似
print scalar $c->length(),"\n"; # prints 3
$x->mantissa();
傳回 $x 的有符號尾數,作為 Math::BigInt。
$x->exponent();
傳回 $x 的指數,作為 Math::BigInt。
$x->parts();
傳回有效數字 (尾數) 和指數,作為整數。在 Math::BigFloat 中,兩者都傳回為 Math::BigInt 物件。
傳回有效數字 (尾數) 和指數,作為整數。在純量內容中,只傳回有效數字。有效數字是絕對值最小的整數。sparts()
的輸出對應於 bsstr()
的輸出。
在 Math::BigInt 中,這個方法與 parts()
相同。
傳回對應於正規化表示法的有效數字 (尾數) 和指數。在純量內容中,只傳回有效數字。對於有限非零數字,有效數字的絕對值大於或等於 1,小於 10。nparts()
的輸出對應於 bnstr()
的輸出。在 Math::BigInt 中,如果有效數字無法表示為整數,則會執行升級或傳回 NaN。
傳回對應於工程表示法的有效數字 (尾數) 和指數。在純量內容中,只傳回有效數字。對於有限非零數字,有效數字的絕對值大於或等於 1,小於 1000,而指數是 3 的倍數。eparts()
的輸出對應於 bestr()
的輸出。在 Math::BigInt 中,如果有效數字無法表示為整數,則會執行升級或傳回 NaN。
傳回整數部分和小數部分。如果小數部分無法表示為整數,則會執行升級或傳回 NaN。dparts()
的輸出對應於 bdstr()
的輸出。
傳回最小的可能分子和分母,使分子除以分母後得到原始值。對於有限數字,兩個值都是整數。助記符:分數。
與 "denominator()" 一起傳回最小的整數,使分子除以分母後重現原始值。使用 Math::BigInt 時,numerator() 只會傳回呼叫函數的副本。
與 「分子()」 一起傳回最小的整數,使分子除以分母會產生原始值。使用 Math::BigInt 時,分母() 永遠會傳回 1 或 NaN。
傳回一個使用十進位表示法的數字字串。在 Math::BigFloat 中,輸出會根據目前的準確度或精確度(如果已定義其中任何一個)補零。
傳回一個使用科學記號表示法的數字字串,其中有效數字(尾數)和指數都是整數。輸出對應於 sparts()
的輸出。
123 is returned as "123e+0"
1230 is returned as "123e+1"
12300 is returned as "123e+2"
12000 is returned as "12e+3"
10000 is returned as "1e+4"
傳回一個使用標準化表示法的數字字串,這是科學記號最常見的變體。對於有限的非零數字,有效數字的絕對值會大於或等於 1,且小於 10。輸出對應於 nparts()
的輸出。
123 is returned as "1.23e+2"
1230 is returned as "1.23e+3"
12300 is returned as "1.23e+4"
12000 is returned as "1.2e+4"
10000 is returned as "1e+4"
傳回一個使用工程記號表示法的數字字串。對於有限的非零數字,有效數字的絕對值會大於或等於 1,且小於 1000,而指數是 3 的倍數。輸出對應於 eparts()
的輸出。
123 is returned as "123e+0"
1230 is returned as "1.23e+3"
12300 is returned as "12.3e+3"
12000 is returned as "12e+3"
10000 is returned as "10e+3"
傳回一個使用十進位表示法的數字字串。輸出對應於 dparts()
的輸出。
123 is returned as "123"
1230 is returned as "1230"
12300 is returned as "12300"
12000 is returned as "12000"
10000 is returned as "10000"
傳回一個使用分數表示法的數字字串。輸出對應於 fparts()
的輸出。
12.345 is returned as "2469/200"
123.45 is returned as "2469/20"
1234.5 is returned as "2469/2"
12345 is returned as "12345"
123450 is returned as "123450"
$x->to_hex();
傳回數字的十六進位字串表示法。另請參閱 from_hex()。
$x->to_bin();
傳回數字的二進位字串表示法。另請參閱 from_bin()。
$x->to_oct();
傳回數字的八進位字串表示法。另請參閱 from_oct()。
$x = Math::BigInt->new("1667327589");
$s = $x->to_bytes(); # $s = "cafe"
傳回數字的位元組字串表示法,使用大端序位元組順序。被運算數必須是非負的有限整數。另請參閱 from_bytes()。
$x = Math::BigInt->new("250");
$x->to_base(2); # returns "11111010"
$x->to_base(8); # returns "372"
$x->to_base(16); # returns "fa"
傳回數字在指定進位制中的字串表示法。如果給定排序序列,排序序列會決定輸出中使用的字元。
以下是一些其他範例
$x = Math::BigInt->new("16")->to_base(3); # returns "121"
$x = Math::BigInt->new("44027")->to_base(36); # returns "XYZ"
$x = Math::BigInt->new("58314")->to_base(42); # returns "Why"
$x = Math::BigInt->new("4")->to_base(2, "-|"); # returns "|--"
請參閱 from_base() 以取得資訊和範例。
將給定的數字轉換為給定的進制。此方法等同於 _to_base()
,但會傳回陣列中的數字,而非字串中的字元。在輸出中,第一個元素是最重要的。與 _to_base()
不同的是,所有輸入值都可以任意大。
$x = Math::BigInt->new(13);
$x->to_base_num(2); # returns [1, 1, 0, 1]
$x = Math::BigInt->new(65191);
$x->to_base_num(128); # returns [3, 125, 39]
$x->as_hex();
與 to_hex()
相同,但加上「0x」前綴。
$x->as_bin();
與 to_bin()
相同,但加上「0b」前綴。
$x->as_oct();
與 to_oct()
相同,但加上「0」前綴。
這只是 to_bytes()
的別名。
print $x->numify();
從 $x 傳回 Perl 純量。每當需要純量時,就會自動使用它,例如在陣列索引運算中。
這些公用程式方法公開
取得使用十進位表示法的任何有效數字的字串,並將其轉換為使用十進位浮點表示法的數字字串。輸出包含五個部分,以連接方式組成:尾數符號、尾數絕對值(最小整數)、字母「e」、指數符號和指數絕對值。如果輸入無效,則不傳回任何內容。
$str2 = $class -> dec_str_to_dec_flt_str($str1);
一些範例
Input Output
31400.00e-4 +314e-2
-0.00012300e8 -123e+2
0 +0e+0
取得使用十六進位表示法的任何有效數字的字串,並將其轉換為使用十進位浮點表示法的數字字串。輸出的格式與 "dec_str_to_dec_flt_str()" 相同。
$str2 = $class -> hex_str_to_dec_flt_str($str1);
一些範例
Input Output
0xff +255e+0
一些範例
使用八進制表示法表示任何有效數字的字串,並將其轉換為使用十進制浮點表示法表示的相同數字的字串。輸出的格式與 "dec_str_to_dec_flt_str()" 相同。
$str2 = $class -> oct_str_to_dec_flt_str($str1);
使用二進制表示法表示任何有效數字的字串,並將其轉換為使用十進制浮點表示法表示的相同數字的字串。輸出的格式與 "dec_str_to_dec_flt_str()" 相同。
$str2 = $class -> bin_str_to_dec_flt_str($str1);
使用十進制表示法表示任何有效數字的字串,並將其轉換為使用十進制表示法表示的相同數字的字串。如果數字表示整數,輸出將包含符號和絕對值。如果數字表示非整數,輸出將包含符號、數字的整數部分、小數點「.」以及數字的小數部分(不含尾數零)。如果輸入無效,則不傳回任何內容。
使用十六進制表示法表示任何有效數字的字串,並將其轉換為使用十進制表示法表示的相同數字的字串。輸出的格式與 "dec_str_to_dec_str()" 相同。
使用八進制表示法表示任何有效數字的字串,並將其轉換為使用十進制表示法表示的相同數字的字串。輸出的格式與 "dec_str_to_dec_str()" 相同。
使用二進制表示法表示任何有效數字的字串,並將其轉換為使用十進制表示法表示的相同數字的字串。輸出的格式與 "dec_str_to_dec_str()" 相同。
Math::BigInt 和 Math::BigFloat 完全支援基於四捨五入的準確度和精確度,兩者皆在每次運算後自動進行,也可以手動進行。
本節說明 Math::BigInt 和 Math::BigFloat 中的準確度/精確度處理,說明其過去和現在的用法,並完整說明所有術語和縮寫。
尚未實作的事項(但有正確說明)會標示為「!」,需要解答的事項會標示為「?」。
下一個段落簡短說明這裡使用的術語(因為這些術語可能與其他人或文件使用的術語不同)。
在本文檔的其餘部分,將使用快捷鍵 A(代表準確度)、P(代表精度)、F(後備)和 R(捨入模式)。
精度是小數點前(正數)或後(負數)的固定位數。例如,123.45 的精度為 -2。0 表示整數,例如 123(或 120)。精度為 2 表示小數點左側至少有兩個數字為零,因此 P = 1 的 123 會變成 120。請注意,小數點前有零的數字可能具有不同的精度,因為 1200 的 P 可以是 0、1 或 2(取決於初始值)。當小數點後的數字為零時,它也可能具有 p < 0。
字串輸出(浮點數)會以零填充
Initial value P A Result String
------------------------------------------------------------
1234.01 -3 1000 1000
1234 -2 1200 1200
1234.5 -1 1230 1230
1234.001 1 1234 1234.0
1234.01 0 1234 1234
1234.01 2 1234.01 1234.01
1234.01 5 1234.01 1234.01000
對於 Math::BigInt 物件,不會進行填充。
有效數字的數量。不計算前導零。當數字中含有零或尾數零時,數字的準確度可能大於非零數字。例如,123.456 的 A 為 6,10203 的 A 為 5,123.0506 的 A 為 7,123.45000 的 A 為 8,0.000123 的 A 為 3。
字串輸出(浮點數)會以零填充
Initial value P A Result String
------------------------------------------------------------
1234.01 3 1230 1230
1234.01 6 1234.01 1234.01
1234.1 8 1234.1 1234.1000
對於 Math::BigInt 物件,不會進行填充。
當 A 和 P 都未定義時,這會在除數字時用作後備準確度。
在捨入數字時,可以使用不同的「樣式」或「種類」的捨入。(請注意,Math::Round 中的隨機捨入並未實作。)
這些捨入模式總是朝同一個方向捨入。
朝零捨入。移除捨入位置之後的所有數字,亦即用零取代它們。因此,捨入至十位數(P=1)的 987.65 會變成 980,捨入至第四個有效數字會變成 987.6(A=4)。捨入至小數點後第二位(P=-2)的 123.456 會變成 123.46。這對應於 IEEE 754 捨入模式「roundTowardZero」。
這些捨入模式會捨入至最接近的數字。它們在決定在出現平手時朝哪個方向捨入的方式上有所不同。
四捨五入至最接近的偶數位數,例如,四捨五入至最接近整數時,-5.5 變成 -6,4.5 變成 4,但 4.501 變成 5。這對應到 IEEE 754 四捨五入模式 'roundTiesToEven'。
四捨五入至最接近的奇數位數,例如,四捨五入至最接近整數時,4.5 變成 5,-5.5 變成 -5,但 5.501 變成 6。這對應到 IEEE 754 四捨五入模式 'roundTiesToOdd'。
四捨五入至正無限大,亦即,永遠向上捨入。例如,四捨五入至最接近整數時,4.5 變成 5,-5.5 變成 -5,而 4.501 也變成 5。這對應到 IEEE 754 四捨五入模式 'roundTiesToPositive'。
四捨五入至負無限大,亦即,永遠向下捨入。例如,四捨五入至最接近整數時,4.5 變成 4,-5.5 變成 -6,但 4.501 變成 5。這對應到 IEEE 754 四捨五入模式 'roundTiesToNegative'。
四捨五入至零,亦即,將正數向下捨入,將負數向上捨入。例如,四捨五入至最接近整數時,4.5 變成 4,-5.5 變成 -5,但 4.501 變成 5。這對應到 IEEE 754 四捨五入模式 'roundTiesToZero'。
四捨五入遠離零,亦即,四捨五入至絕對值最大的數字。例如,四捨五入至最接近整數時,-1.5 變成 -2,1.5 變成 2,而 1.49 變成 1。這對應到 IEEE 754 四捨五入模式 'roundTiesToAway'。
MBI/MBF (與 Perl 版本 <= 5.7.2 一起附帶的舊核心程式碼) 中 A 和 P 的處理方式如下
* bfround($p) is able to round to $p number of digits after the decimal
point
* otherwise P is unused
* bround($a) rounds to $a significant digits
* only bdiv() and bsqrt() take A as (optional) parameter
+ other operations simply create the same number (bneg etc), or
more (bmul) of digits
+ rounding/truncating is only done when explicitly calling one
of bround or bfround, and never for Math::BigInt (not implemented)
* bsqrt() simply hands its accuracy argument over to bdiv.
* the documentation and the comment in the code indicate two
different ways on how bdiv() determines the maximum number
of digits it should calculate, and the actual code does yet
another thing
POD:
max($Math::BigFloat::div_scale,length(dividend)+length(divisor))
Comment:
result has at most max(scale, length(dividend), length(divisor)) digits
Actual code:
scale = max(scale, length(dividend)-1,length(divisor)-1);
scale += length(divisor) - length(dividend);
So for lx = 3, ly = 9, scale = 10, scale will actually be 16 (10
So for lx = 3, ly = 9, scale = 10, scale will actually be 16
(10+9-3). Actually, the 'difference' added to the scale is cal-
culated from the number of "significant digits" in dividend and
divisor, which is derived by looking at the length of the man-
tissa. Which is wrong, since it includes the + sign (oops) and
actually gets 2 for '+100' and 4 for '+101'. Oops again. Thus
124/3 with div_scale=1 will get you '41.3' based on the strange
assumption that 124 has 3 significant digits, while 120/7 will
get you '17', not '17.1' since 120 is thought to have 2 signif-
icant digits. The rounding after the division then uses the
remainder and $y to determine whether it must round up or down.
? I have no idea which is the right way. That's why I used a slightly more
? simple scheme and tweaked the few failing testcases to match it.
這是它現在運作的方式
* You can set the A global via Math::BigInt->accuracy() or
Math::BigFloat->accuracy() or whatever class you are using.
* You can also set P globally by using Math::SomeClass->precision()
likewise.
* Globals are classwide, and not inherited by subclasses.
* to undefine A, use Math::SomeClass->accuracy(undef);
* to undefine P, use Math::SomeClass->precision(undef);
* Setting Math::SomeClass->accuracy() clears automatically
Math::SomeClass->precision(), and vice versa.
* To be valid, A must be > 0, P can have any value.
* If P is negative, this means round to the P'th place to the right of the
decimal point; positive values mean to the left of the decimal point.
P of 0 means round to integer.
* to find out the current global A, use Math::SomeClass->accuracy()
* to find out the current global P, use Math::SomeClass->precision()
* use $x->accuracy() respective $x->precision() for the local
setting of $x.
* Please note that $x->accuracy() respective $x->precision()
return eventually defined global A or P, when $x's A or P is not
set.
* When you create a number, you can give the desired A or P via:
$x = Math::BigInt->new($number,$A,$P);
* Only one of A or P can be defined, otherwise the result is NaN
* If no A or P is give ($x = Math::BigInt->new($number) form), then the
globals (if set) will be used. Thus changing the global defaults later on
will not change the A or P of previously created numbers (i.e., A and P of
$x will be what was in effect when $x was created)
* If given undef for A and P, NO rounding will occur, and the globals will
NOT be used. This is used by subclasses to create numbers without
suffering rounding in the parent. Thus a subclass is able to have its own
globals enforced upon creation of a number by using
$x = Math::BigInt->new($number,undef,undef):
use Math::BigInt::SomeSubclass;
use Math::BigInt;
Math::BigInt->accuracy(2);
Math::BigInt::SomeSubclass->accuracy(3);
$x = Math::BigInt::SomeSubclass->new(1234);
$x is now 1230, and not 1200. A subclass might choose to implement
this otherwise, e.g. falling back to the parent's A and P.
* If A or P are enabled/defined, they are used to round the result of each
operation according to the rules below
* Negative P is ignored in Math::BigInt, since Math::BigInt objects never
have digits after the decimal point
* Math::BigFloat uses Math::BigInt internally, but setting A or P inside
Math::BigInt as globals does not tamper with the parts of a Math::BigFloat.
A flag is used to mark all Math::BigFloat numbers as 'never round'.
* It only makes sense that a number has only one of A or P at a time.
If you set either A or P on one object, or globally, the other one will
be automatically cleared.
* If two objects are involved in an operation, and one of them has A in
effect, and the other P, this results in an error (NaN).
* A takes precedence over P (Hint: A comes before P).
If neither of them is defined, nothing is used, i.e. the result will have
as many digits as it can (with an exception for bdiv/bsqrt) and will not
be rounded.
* There is another setting for bdiv() (and thus for bsqrt()). If neither of
A or P is defined, bdiv() will use a fallback (F) of $div_scale digits.
If either the dividend's or the divisor's mantissa has more digits than
the value of F, the higher value will be used instead of F.
This is to limit the digits (A) of the result (just consider what would
happen with unlimited A and P in the case of 1/3 :-)
* bdiv will calculate (at least) 4 more digits than required (determined by
A, P or F), and, if F is not used, round the result
(this will still fail in the case of a result like 0.12345000000001 with A
or P of 5, but this can not be helped - or can it?)
* Thus you can have the math done by on Math::Big* class in two modi:
+ never round (this is the default):
This is done by setting A and P to undef. No math operation
will round the result, with bdiv() and bsqrt() as exceptions to guard
against overflows. You must explicitly call bround(), bfround() or
round() (the latter with parameters).
Note: Once you have rounded a number, the settings will 'stick' on it
and 'infect' all other numbers engaged in math operations with it, since
local settings have the highest precedence. So, to get SaferRound[tm],
use a copy() before rounding like this:
$x = Math::BigFloat->new(12.34);
$y = Math::BigFloat->new(98.76);
$z = $x * $y; # 1218.6984
print $x->copy()->bround(3); # 12.3 (but A is now 3!)
$z = $x * $y; # still 1218.6984, without
# copy would have been 1210!
+ round after each op:
After each single operation (except for testing like is_zero()), the
method round() is called and the result is rounded appropriately. By
setting proper values for A and P, you can have all-the-same-A or
all-the-same-P modes. For example, Math::Currency might set A to undef,
and P to -2, globally.
?Maybe an extra option that forbids local A & P settings would be in order,
?so that intermediate rounding does not 'poison' further math?
* you will be able to give A, P and R as an argument to all the calculation
routines; the second parameter is A, the third one is P, and the fourth is
R (shift right by one for binary operations like badd). P is used only if
the first parameter (A) is undefined. These three parameters override the
globals in the order detailed as follows, i.e. the first defined value
wins:
(local: per object, global: global default, parameter: argument to sub)
+ parameter A
+ parameter P
+ local A (if defined on both of the operands: smaller one is taken)
+ local P (if defined on both of the operands: bigger one is taken)
+ global A
+ global P
+ global F
* bsqrt() will hand its arguments to bdiv(), as it used to, only now for two
arguments (A and P) instead of one
* You can set A or P locally by using $x->accuracy() or
$x->precision()
and thus force different A and P for different objects/numbers.
* Setting A or P this way immediately rounds $x to the new value.
* $x->accuracy() clears $x->precision(), and vice versa.
* the rounding routines will use the respective global or local settings.
bround() is for accuracy rounding, while bfround() is for precision
* the two rounding functions take as the second parameter one of the
following rounding modes (R):
'even', 'odd', '+inf', '-inf', 'zero', 'trunc', 'common'
* you can set/get the global R by using Math::SomeClass->round_mode()
or by setting $Math::SomeClass::round_mode
* after each operation, $result->round() is called, and the result may
eventually be rounded (that is, if A or P were set either locally,
globally or as parameter to the operation)
* to manually round a number, call $x->round($A,$P,$round_mode);
this will round the number by using the appropriate rounding function
and then normalize it.
* rounding modifies the local settings of the number:
$x = Math::BigFloat->new(123.456);
$x->accuracy(5);
$x->bround(4);
Here 4 takes precedence over 5, so 123.5 is the result and $x->accuracy()
will be 4 from now on.
* R: 'even'
* F: 40
* A: undef
* P: undef
* The defaults are set up so that the new code gives the same results as
the old code (except in a few cases on bdiv):
+ Both A and P are undefined and thus will not be used for rounding
after each operation.
+ round() is thus a no-op, unless given extra parameters A and P
雖然 Math::BigInt 廣泛處理 inf 和 NaN,但仍有一些怪癖。
這些 perl 常式目前(截至 Perl v.5.8.6)無法處理傳遞的 inf。
te@linux:~> perl -wle 'print 2 ** 3333'
Inf
te@linux:~> perl -wle 'print 2 ** 3333 == 2 ** 3333'
1
te@linux:~> perl -wle 'print oct(2 ** 3333)'
0
te@linux:~> perl -wle 'print hex(2 ** 3333)'
Illegal hexadecimal digit 'I' ignored at -e line 1.
0
如果您傳遞 Math::BigInt->binf() 物件,也會發生相同的問題。由於無法覆載這些常式,因此無法從 Math::BigInt 修復此問題。
您不應該關心或依賴內部表示形式;它可能會在沒有通知的情況下變更。僅使用 $x->sign();
等方法呼叫,而不是依賴內部表示形式。
數學運算由後端函式庫執行。不需要指定要使用哪個後端函式庫,但有些後端函式庫比預設函式庫快很多。
預設函式庫是 Math::BigInt::Calc,它以純 Perl 實作,因此不需要編譯器。
簡單的案例
use Math::BigInt;
等於說
use Math::BigInt try => 'Calc';
您可以使用不同的後端函式庫,例如
use Math::BigInt try => 'GMP';
它嘗試載入 Math::BigInt::GMP 函式庫,如果無法載入指定的函式庫,則會回退到預設函式庫。
可以透過逗號分隔來指定多個函式庫,例如
use Math::BigInt try => 'GMP,Pari';
如果您要求特定的函式庫組,並且不允許回退到預設函式庫,請使用「only」指定它們,
use Math::BigInt only => 'GMP,Pari';
如果您偏好特定的函式庫組,但希望在使用回退函式庫時看到警告,請使用「lib」指定它們,
use Math::BigInt lib => 'GMP,Pari';
以下會先嘗試尋找 Math::BigInt::Foo,然後是 Math::BigInt::Bar,如果這也失敗,則會回退到 Math::BigInt::Calc
use Math::BigInt try => 'Foo,Math::BigInt::Bar';
注意:通用套件不應明確說明要使用的函式庫;讓腳本作者決定哪個最好。
Math::BigInt::GMP、Math::BigInt::Pari 和 Math::BigInt::GMPz 在涉及大數字的情況下比 Math::BigInt::Calc 快很多。然而,這些函式庫在處理非常小的數字(約小於 20 位數)以及將非常大的數字轉換為小數(例如用於列印、捨入、計算其小數長度等)時較慢。
因此,請仔細選擇您要使用的函式庫。
不同的底層函式庫使用不同的格式來儲存數字,因此混合使用它們會無法運作。您不應該依賴數字具有特定的內部格式。
請參閱相關的數學函式庫模組文件以取得進一步的詳細資訊。
第一個成功載入的函式庫將會是使用中的函式庫。任何進一步載入不同模組的嘗試都將會被忽略。這是為了避免模組 A 需要數學函式庫 X,而模組 B 需要數學函式庫 Y 的情況,導致模組 A 和 B 不相容。例如,
use Math::BigInt; # loads default "Calc"
use Math::BigFloat only => "GMP"; # ignores "GMP"
符號為 '+', '-', 'NaN', '+inf' 或 '-inf'。
當輸入參數不是數字或為 0/0 的結果時,會使用 'NaN' 符號來表示結果。'+inf' 和 '-inf' 分別表示正無窮大和負無窮大。當將正數除以 0 時會得到 '+inf',而將任何負數除以 0 時會得到 '-inf'。
use Math::BigInt;
sub bigint { Math::BigInt->new(shift); }
$x = Math::BigInt->bstr("1234") # string "1234"
$x = "$x"; # same as bstr()
$x = Math::BigInt->bneg("1234"); # Math::BigInt "-1234"
$x = Math::BigInt->babs("-12345"); # Math::BigInt "12345"
$x = Math::BigInt->bnorm("-0.00"); # Math::BigInt "0"
$x = bigint(1) + bigint(2); # Math::BigInt "3"
$x = bigint(1) + "2"; # ditto ("2" becomes a Math::BigInt)
$x = bigint(1); # Math::BigInt "1"
$x = $x + 5 / 2; # Math::BigInt "3"
$x = $x ** 3; # Math::BigInt "27"
$x *= 2; # Math::BigInt "54"
$x = Math::BigInt->new(0); # Math::BigInt "0"
$x--; # Math::BigInt "-1"
$x = Math::BigInt->badd(4,5) # Math::BigInt "9"
print $x->bsstr(); # 9e+0
取整範例
use Math::BigFloat;
use Test::More;
$x = Math::BigFloat->new(123.4567);
$y = Math::BigFloat->new(123.456789);
Math::BigFloat->accuracy(4); # no more A than 4
is ($x->copy()->bround(),123.4); # even rounding
print $x->copy()->bround(),"\n"; # 123.4
Math::BigFloat->round_mode('odd'); # round to odd
print $x->copy()->bround(),"\n"; # 123.5
Math::BigFloat->accuracy(5); # no more A than 5
Math::BigFloat->round_mode('odd'); # round to odd
print $x->copy()->bround(),"\n"; # 123.46
$y = $x->copy()->bround(4),"\n"; # A = 4: 123.4
print "$y, ",$y->accuracy(),"\n"; # 123.4, 4
Math::BigFloat->accuracy(undef); # A not important now
Math::BigFloat->precision(2); # P important
print $x->copy()->bnorm(),"\n"; # 123.46
print $x->copy()->bround(),"\n"; # 123.46
轉換範例
my $x = Math::BigInt->new('0b1'.'01' x 123);
print "bin: ",$x->as_bin()," hex:",$x->as_hex()," dec: ",$x,"\n";
在 use Math::BigInt ':constant'
之後,給定範圍內的所有數字文字都會轉換為 Math::BigInt
物件。此轉換會在編譯時發生。每個非整數都會轉換為 NaN。
例如,
perl -MMath::BigInt=:constant -le 'print 2**150'
會列印 2**150
的確切值。請注意,如果不將常數轉換為物件,則會使用 Perl 純量計算表達式 2**150
,這會導致不準確的結果。
請注意,字串不受影響,因此
use Math::BigInt qw/:constant/;
$x = "1234567890123456789012345678901234567890"
+ "123456789123456789";
會提供您預期的結果。您需要在至少一個運算元周圍加上明確的 Math::BigInt->new()。您還應該引用大型常數以防止精度損失
use Math::BigInt;
$x = Math::BigInt->new("1234567889123456789123456789123456789");
在沒有引號的情況下,Perl 會先在編譯時將大數字轉換為浮點常數,然後在執行時將結果轉換為 Math::BigInt 物件,這會導致不準確的結果。
Perl(和此模組)接受十六進位、八進位和二進位浮點文字,但在 v5.32.0 之前的 Perl 版本中使用它們時要小心,因為某些版本的 Perl 會在不提示的情況下提供錯誤的結果。以下是撰寫數字小數 314 的不同方式的一些範例。
十六進位浮點文字
0x1.3ap+8 0X1.3AP+8
0x1.3ap8 0X1.3AP8
0x13a0p-4 0X13A0P-4
八進位浮點文字(帶有「0」前綴)
01.164p+8 01.164P+8
01.164p8 01.164P8
011640p-4 011640P-4
八進位浮點文字(帶有「0o」前綴)(需要 v5.34.0)
0o1.164p+8 0O1.164P+8
0o1.164p8 0O1.164P8
0o11640p-4 0O11640P-4
二進位浮點文字
0b1.0011101p+8 0B1.0011101P+8
0b1.0011101p8 0B1.0011101P8
0b10011101000p-2 0B10011101000P-2
使用 $x += $y 等形式會比 $x = $x + $y 來的快,因為後者必須複製 $x。對於長數字而言,複製會耗費高達 20% 的效能(對於加法/減法而言,比乘法/除法少)。如果 $y 與 $x 相比非常小,那麼 $x += $y 會比 $x = $x + $y 快很多,因為複製 $x 所花的時間比實際加法還要長。
透過稱為寫入時複製的技術,可以將使用覆寫複製的成本降到最低,甚至完全避免。COW 的測試實作顯示,對於覆寫的數學運算有效能提升,但由於所有其他運算的恆定開銷,導致效能下降。因此,Math::BigInt 目前不使用 COW。
此模組的重寫版本(相較於 v0.01)在某些運算上較慢,例如 new()
、bstr()
和 numify()
。原因是它現在執行更多工作,並處理更多案例。這些運算所花的時間通常會在其他數學運算中獲得補償,因此平均來說,程式碼應該會(大幅)變快。如果沒有,請聯絡作者。
某些運算對於小數字來說可能會較慢,但對於大數字來說會顯著變快。其他運算現在是常數(O(1),例如 bneg()
、babs()
等),而不是 O(N),因此幾乎總是會花更少時間。這些最佳化是故意執行的。
如果您發現 Calc 模組太慢,請嘗試安裝任何替代模組,看看是否有幫助。
您可以使用替代函式庫來驅動 Math::BigInt。請參閱"MATH LIBRARY"章節以取得更多資訊。
如需更多基準測試結果,請參閱http://bloodgate.com/perl/benchmarks.html。
只要遵循一些簡單的規則,Math::BigInt 的基本設計就可以使用非常少的工作建立簡單的子類別
公開 API 必須保持一致,也就是說,如果子類別覆寫加法,則子類別必須使用相同的名稱,在本例中為 badd()。原因是 Math::BigInt 已最佳化為直接呼叫物件方法。
私人物件雜湊金鑰,例如 $x->{sign}
,不能變更,但可以新增其他金鑰,例如 $x->{_custom}
。
所有現有的物件雜湊金鑰都有存取函式,應使用這些函式,而不是直接存取內部雜湊金鑰。原因是 Math::BigInt 本身具有可插入的介面,允許它支援不同的儲存方法。
如果需要變更更基本的行為,更複雜的子類別可能必須複製 Math::BigInt 內部更多邏輯。一個僅需要變更輸出的子類別只需要覆寫 bstr()
。
所有其他物件方法和覆寫函式都可以直接從父類別繼承。
至少,任何子類別都需要提供自己的 new()
,並且可以在物件中儲存額外的雜湊金鑰。還有一些必須定義的套件全域變數,例如:
# Globals
$accuracy = undef;
$precision = -2; # round to 2 decimal places
$round_mode = 'even';
$div_scale = 40;
此外,您可能需要提供以下兩個全域變數,以允許自動升級和自動降級正常運作
$upgrade = undef;
$downgrade = undef;
這允許 Math::BigInt 從子類別正確擷取套件全域變數,例如 $SubClass::precision
。請參閱 t/Math/BigInt/Subclass.pm 或 t/Math/BigFloat/SubClass.pm 完整功能子類別範例。
別忘了
use overload;
在您的子類別中自動繼承父類別的覆寫。如果您願意,可以變更覆寫的一部分,請參閱 Math::String 以取得範例。
當這樣使用時
use Math::BigInt upgrade => 'Foo::Bar';
某些運算會「升級」其計算,因此結果為類別 Foo::Bar。這通常與 Math::BigFloat 搭配使用
use Math::BigInt upgrade => 'Math::BigFloat';
作為捷徑,您可以使用模組 bignum
use bignum;
也適用於單行
perl -Mbignum -le 'print 2 ** 255'
這使得可以混合不同類別的引數(例如 2.5 + 2),以及保留準確度(例如 sqrt(3))。
注意:此功能尚未完全實作。
下列方法會無條件升級自己;也就是說,如果升級有效,它們總是會交出工作
div bsqrt blog bexp bpi bsin bcos batan batan2
所有其他方法僅在它們的其中一個(或全部)引數屬於 $upgrade 中所述的類別時才會升級自己。
Math::BigInt
預設不匯出任何內容,但可以匯出下列方法
bgcd
blcm
有些事情可能無法如您預期般運作。下列文件記載已知會造成問題的事項
bstr()
和 bsstr()
以及透過覆寫字串化都會捨棄開頭的「+」。這是為了與 Perl 保持一致,並使 cmp
(特別是與覆寫搭配使用)能如您預期般運作。它也解決了 Test.pm
和 Test::More 的問題,它們會在比較引數之前將其字串化。
當被問及是否要完全捨棄「+」,或只讓 cmp
運作時,Mark Biggar 表示
I agree (with the first alternative), don't add the '+' on positive
numbers. It's not as important anymore with the new internal form
for numbers. It made doing things like abs and neg easier, but
those have to be done differently now anyway.
因此,下列範例現在會如預期般運作
use Test::More tests => 1;
use Math::BigInt;
my $x = Math::BigInt -> new(3*3);
my $y = Math::BigInt -> new(3*3);
is($x,3*3, 'multiplication');
print "$x eq 9" if $x eq $y;
print "$x eq 9" if $x eq '9';
print "$x eq 9" if $x eq 3*3;
此外,下列範例仍然會運作
print "$x == 9" if $x == $y;
print "$x == 9" if $x == 9;
print "$x == 9" if $x == 3*3;
現在有一個 bsstr()
方法可以取得科學記號字串,例如 1e+2
而不是 100
。請注意,重載的「eq」總是使用 bstr() 進行比較,但 Perl 會將某些數字表示為 100,而其他數字表示為 1e+308。如有疑問,請在將它們作為字串比較之前,將兩個參數都轉換為 Math::BigInt
use Test::More tests => 3;
use Math::BigInt;
$x = Math::BigInt->new('1e56');
$y = 1e56;
is($x,$y); # fails
is($x->bsstr(), $y); # okay
$y = Math::BigInt->new($y);
is($x, $y); # okay
或者,只需使用 <=>
進行比較,這總是正確的。目前還沒有辦法取得自動表示為字串的數字,其方式與 Perl 表示它的方式完全相符。
另請參閱有關 "無窮大和非數字" 的部分,以了解比較 NaN 的問題。
int()
會傳回(至少對於 Perl v5.7.1 以上版本)另一個 Math::BigInt,而不是 Perl 標量
$x = Math::BigInt->new(123);
$y = int($x); # 123 as a Math::BigInt
$x = Math::BigFloat->new(123.45);
$y = int($x); # 123 as a Math::BigFloat
如果您想要一個真正的 Perl 標量,請使用 numify()
$y = $x->numify(); # 123 as a scalar
不過,這很少有必要,因為這會自動完成,例如當您存取陣列時
$z = $array[$x]; # does work automatically
小心
$x = Math::BigFloat->new(5);
$y = $x;
這會建立對相同物件的第二次參照,並將其儲存在 $y 中。因此,任何修改 $x 的動作(重載的運算子除外)也會修改 $y,反之亦然。或者換句話說,=
只有在您僅透過重載的數學修改 Math::BigInt 物件時才是安全的。只要您使用一個方法呼叫,它就會中斷
$x->bmul(2);
print "$x, $y\n"; # prints '10, 10'
如果您想要 $x 的真實拷貝,請使用
$y = $x->copy();
您也可以像這樣鏈結呼叫,這會先建立一個拷貝,然後將它乘以 2
$y = $x->copy()->bmul(2);
另請參閱 overload.pm 關於 =
的文件。
下列
$x = -$x;
比
$x->bneg();
慢,因為重載會呼叫 sub($x,0,1);
而不是 neg($x)
。第一個變體需要保留 $x,因為它不知道它稍後會被覆寫。這會建立 $x 的拷貝並採用 O(N),但 $x->bneg() 是 O(1)。
對於重載的運算子,決定呼叫哪個方法的是第一個(主導)運算元。以下是一些範例,顯示在各種情況下實際呼叫了什麼。
use Math::BigInt;
use Math::BigFloat;
$mbf = Math::BigFloat->new(5);
$mbi2 = Math::BigInt->new(5);
$mbi = Math::BigInt->new(2);
# what actually gets called:
$float = $mbf + $mbi; # $mbf->badd($mbi)
$float = $mbf / $mbi; # $mbf->bdiv($mbi)
$integer = $mbi + $mbf; # $mbi->badd($mbf)
$integer = $mbi2 / $mbi; # $mbi2->bdiv($mbi)
$integer = $mbi2 / $mbf; # $mbi2->bdiv($mbf)
例如,Math::BigInt->bdiv() 總是傳回 Math::BigInt,無論第二個運算元是否為 Math::BigFloat。若要取得 Math::BigFloat,您需要手動呼叫運算,確保每個運算元都已經是 Math::BigFloat,或透過 Math::BigFloat->new() 轉換為該類型
$float = Math::BigFloat->new($mbi2) / $mbi; # = 2.5
小心不要轉換整個表達式,因為這會轉換結果,而這時已經太遲了
$float = Math::BigFloat->new($mbi2 / $mbi); # = 2
小心以下更複雜表達式的順序
$integer = ($mbi2 + $mbi) / $mbf; # int / float => int
$integer = $mbi2 / Math::BigFloat->new($mbi); # ditto
如有疑問,請將表達式分解成更簡單的詞彙,或將所有運算元轉換為所需的結果類型。
標量值有點不同,因為
$float = 2 + $mbf;
$float = $mbf + 2;
由於重載運算的方式,兩個都產生正確的類型。
此區段也適用於其他重載運算套件,例如 Math::String。
你的問題的其中一個解決方案可能是自動升級|升級。請參閱實用程式 bignum、bigint 和 bigrat,以取得執行此操作的簡易方法。
請將任何錯誤或功能要求回報至 bug-math-bigint at rt.cpan.org
,或透過 https://rt.cpan.org/Ticket/Create.html?Queue=Math-BigInt 網路介面(需要登入)。我們會收到通知,然後當我進行變更時,你會自動收到錯誤進度的通知。
你可以使用 perldoc 指令尋找此模組的說明文件。
perldoc Math::BigInt
你也可以在以下位置尋找資訊
GitHub
RT:CPAN 的要求追蹤器
MetaCPAN
CPAN 測試人員矩陣
CPAN 評分
Bignum 郵件清單
發佈到郵件清單
bignum at lists.scsys.co.uk
檢視郵件清單
訂閱/取消訂閱
此程式為免費軟體;你可以根據 Perl 本身的條款重新散布或修改它。
Math::BigFloat 和 Math::BigRat,以及後端 Math::BigInt::FastCalc、Math::BigInt::GMP 和 Math::BigInt::Pari。
實用程式 bignum、bigint 和 bigrat 也可能很有用,因為它們至少部分解決了自動升級/降級問題。
Mark Biggar,Ilya Zakharevich 的重載介面,1996-2001。
Tels http://bloodgate.com 完全改寫,2001-2008。
Florian Ragwitz <flora@cpan.org>,2010。
Peter John Acklam <pjacklam@gmail.com>,2011-。
許多人以一種或多種方式為最終的野獸做出貢獻,請參閱 CREDITS 檔案以取得(不完整的)清單。如果您遺漏了您的名字,請寄信給我。謝謝您!