内容

名称

Math::BigRat - 任意大小的有理数数学包

概要

use Math::BigRat;

my $x = Math::BigRat->new('3/7'); $x += '5/9';

print $x->bstr(), "\n";
print $x ** 2, "\n";

my $y = Math::BigRat->new('inf');
print "$y ", ($y->is_inf ? 'is' : 'is not'), " infinity\n";

my $z = Math::BigRat->new(144); $z->bsqrt();

描述

Math::BigRat 通过提供对任意大有理数的支持来补充 Math::BigInt 和 Math::BigFloat。

数学库

您可以使用以下方法更改执行低级数学运算的底层模块

use Math::BigRat try => 'GMP';

注意:这需要安装 Math::BigInt::GMP。

以下代码将首先尝试查找 Math::BigInt::Foo,然后查找 Math::BigInt::Bar,如果这两个都失败,则恢复到 Math::BigInt::Calc

use Math::BigRat try => 'Foo,Math::BigInt::Bar';

如果您希望在回退发生时收到警告,请将 "try" 替换为 "lib"

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

如果您希望代码改为终止,请将 "try" 替换为 "only"

use Math::BigRat only => 'Foo,Math::BigInt::Bar';

方法

此处未列出的任何方法都来自 Math::BigFloat(或 Math::BigInt),因此请确保您查看这两个模块以获取更多信息。

new()
$x = Math::BigRat->new('1/3');

创建一个新的 Math::BigRat 对象。输入可以采用多种形式

$x = Math::BigRat->new(123);                            # scalars
$x = Math::BigRat->new('inf');                          # infinity
$x = Math::BigRat->new('123.3');                        # float
$x = Math::BigRat->new('1/3');                          # simple string
$x = Math::BigRat->new('1 / 3');                        # spaced
$x = Math::BigRat->new('1 / 0.1');                      # w/ floats
$x = Math::BigRat->new(Math::BigInt->new(3));           # BigInt
$x = Math::BigRat->new(Math::BigFloat->new('3.1'));     # BigFloat
$x = Math::BigRat->new(Math::BigInt::Lite->new('2'));   # BigLite

# You can also give D and N as different objects:
$x = Math::BigRat->new(
        Math::BigInt->new(-123),
        Math::BigInt->new(7),
     );                      # => -123/7
numerator()
$n = $x->numerator();

返回分子(分数线上的部分)的符号 BigInt 副本。

denominator()
$d = $x->denominator();

返回分母(分数线下的部分)的正 BigInt 副本。

parts()
($n, $d) = $x->parts();

返回一个列表,其中包含(带符号)分子和(无符号)分母作为 BigInt。

dparts()

返回整数部分和小数部分。

fparts()

返回尽可能小的分子和分母,使分子除以分母得到原始值。对于有限数,这两个值都是整数。助记符:分数。

numify()
my $y = $x->numify();

将对象作为标量返回。如果对象不能用普通的 Perl 标量(整数或浮点数)表示,则会丢失一些数据,因此请使用 "as_int()""as_float()" 代替。

每当需要标量时,此例程都会自动使用。

my $x = Math::BigRat->new('3/1');
@array = (0, 1, 2, 3);
$y = $array[$x];                # set $y to 3
as_int()
as_number()
$x = Math::BigRat->new('13/7');
print $x->as_int(), "\n";               # '1'

返回对象的 BigInt 副本,截断为整数。

as_number()as_int() 的别名。

as_float()
$x = Math::BigRat->new('13/7');
print $x->as_float(), "\n";             # '1'

$x = Math::BigRat->new('2/3');
print $x->as_float(5), "\n";            # '0.66667'

返回对象的 BigFloat 副本,保留所需的精度,或默认的 40 位精度。

此方法是在 Math::BigRat 的 v0.22 版本(2008 年 4 月)中添加的。

as_hex()
$x = Math::BigRat->new('13');
print $x->as_hex(), "\n";               # '0xd'

将 BigRat 作为十六进制字符串返回。仅适用于整数。

as_bin()
$x = Math::BigRat->new('13');
print $x->as_bin(), "\n";               # '0x1101'

将 BigRat 作为二进制字符串返回。仅适用于整数。

as_oct()
$x = Math::BigRat->new('13');
print $x->as_oct(), "\n";               # '015'

将 BigRat 作为八进制字符串返回。仅适用于整数。

from_hex()
my $h = Math::BigRat->from_hex('0x10');

从字符串形式的十六进制数创建 BigRat。

from_oct()
my $o = Math::BigRat->from_oct('020');

从字符串形式的八进制数创建 BigRat。

from_bin()
my $b = Math::BigRat->from_bin('0b10000000');

从字符串形式的二进制数创建 BigRat。

bnan()
$x = Math::BigRat->bnan();

创建一个表示 NaN(非数字)的新 BigRat 对象。如果在对象上使用,它将将其设置为 NaN。

$x->bnan();
bzero()
$x = Math::BigRat->bzero();

创建一个表示零的新 BigRat 对象。如果在对象上使用,它将将其设置为零。

$x->bzero();
binf()
$x = Math::BigRat->binf($sign);

创建一个表示无穷大的新 BigRat 对象。可选参数为 '-' 或 '+',指示您想要无穷大还是负无穷大。如果在对象上使用,它将将其设置为无穷大。

$x->binf();
$x->binf('-');
bone()
$x = Math::BigRat->bone($sign);

创建一个表示一的新 BigRat 对象。可选参数为 '-' 或 '+',指示您想要一还是负一。如果在对象上使用,它将将其设置为一。

$x->bone();                 # +1
$x->bone('-');              # -1
length()
$len = $x->length();

返回 $x 的长度(以位数表示),用于整数。

digit()
print Math::BigRat->new('123/1')->digit(1);     # 1
print Math::BigRat->new('123/1')->digit(-1);    # 3

当 X 为整数值时,返回 X 中的第 N 位数字。

bnorm()
$x->bnorm();

将数字简化为最短形式。此例程在需要时会自动调用。

bfac()
$x->bfac();

计算 $x 的阶乘。例如

print Math::BigRat->new('3/1')->bfac(), "\n";   # 1*2*3
print Math::BigRat->new('5/1')->bfac(), "\n";   # 1*2*3*4*5

目前仅适用于整数。

bround()/round()/bfround()

尚未实现。

bmod()
$x->bmod($y);

返回 $x 模 $y。当 $x 为有限值,且 $y 为有限值且非零时,结果与地板除法(F-除法)后的余数相同。此外,如果 $x 和 $y 都是整数,则结果与 Perl 的 % 运算符的结果相同。

bmodinv()
$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'。

bmodpow()
$num->bmodpow($exp,$mod);           # modular exponentiation
                                    # ($num**$exp % $mod)

使用二进制指数运算返回 $num$exp 次方模 $mod 的值。bmodpow 比以下代码要好得多

$num ** $exp % $mod

因为它速度快得多 - 它尽可能地将内部变量缩减到模数,因此它对较小的数字进行操作。

bmodpow 也支持负指数。

bmodpow($num, -1, $mod)

与以下代码完全相同

bmodinv($num, $mod)
bneg()
$x->bneg();

用于就地取反对象。

is_one()
print "$x is 1\n" if $x->is_one();

如果 $x 恰好为 1,则返回 true,否则返回 false。

is_zero()
print "$x is 0\n" if $x->is_zero();

如果 $x 恰好为 0,则返回 true,否则返回 false。

is_pos()/is_positive()
print "$x is >= 0\n" if $x->is_positive();

如果 $x 为正数(大于或等于零),则返回 true,否则返回 false。请注意,'+inf' 也是正数,而 'NaN' 和 '-inf' 不是。

is_positive()is_pos() 的别名。

is_neg()/is_negative()
print "$x is < 0\n" if $x->is_negative();

如果 $x 为负数(小于零),则返回 true,否则返回 false。请注意,'-inf' 也是负数,而 'NaN' 和 '+inf' 不是。

is_negative()is_neg() 的别名。

is_int()
print "$x is an integer\n" if $x->is_int();

如果 $x 的分母为 1(例如,没有小数部分),则返回 true,否则返回 false。请注意,'-inf'、'inf' 和 'NaN' 不是整数。

is_odd()
print "$x is odd\n" if $x->is_odd();

如果 $x 为奇数,则返回 true,否则返回 false。

is_even()
print "$x is even\n" if $x->is_even();

如果 $x 为偶数,则返回 true,否则返回 false。

bceil()
$x->bceil();

将 $x 设置为下一个更大的整数值(例如,将数字截断为整数,然后加 1)。

bfloor()
$x->bfloor();

将 $x 截断为整数值。

bint()
$x->bint();

将 $x 向零取整。

bsqrt()
$x->bsqrt();

计算 $x 的平方根。

broot()
$x->broot($n);

计算 $x 的 N 次方根。

badd()
$x->badd($y);

将 $y 加到 $x 并返回结果。

bmul()
$x->bmul($y);

将 $y 乘以 $x 并返回结果。

bsub()
$x->bsub($y);

从 $x 中减去 $y 并返回结果。

bdiv()
$q = $x->bdiv($y);
($q, $r) = $x->bdiv($y);

在标量上下文中,用 $y 除以 $x 并返回结果。在列表上下文中,执行向下取整除法(F-除法),返回一个整数 $q 和一个余数 $r,使得 $x = $q * $y + $r。余数(模)等于 $x->bmod($y) 返回的值。

binv()
$x->binv();

$x 的倒数。

bdec()
$x->bdec();

将 $x 减 1 并返回结果。

binc()
$x->binc();

将 $x 加 1 并返回结果。

copy()
my $z = $x->copy();

创建对象的深层副本。

有关更多详细信息,请参阅 Math::BigInt 中的文档。

bstr()/bsstr()
my $x = Math::BigRat->new('8/4');
print $x->bstr(), "\n";             # prints 1/2
print $x->bsstr(), "\n";            # prints 1/2

返回表示此对象的字符串。

bcmp()
$x->bcmp($y);

比较 $x 和 $y 并考虑符号。返回 -1、0、1 或 undef。

bacmp()
$x->bacmp($y);

比较 $x 和 $y,同时忽略其符号。返回 -1、0、1 或 undef。

beq()
$x -> beq($y);

当且仅当 $x 等于 $y 时返回 true,否则返回 false。

bne()
$x -> bne($y);

当且仅当 $x 不等于 $y 时返回 true,否则返回 false。

blt()
$x -> blt($y);

当且仅当 $x 等于 $y 时返回 true,否则返回 false。

ble()
$x -> ble($y);

当且仅当 $x 小于或等于 $y 时返回 true,否则返回 false。

bgt()
$x -> bgt($y);

当且仅当 $x 大于 $y 时返回 true,否则返回 false。

bge()
$x -> bge($y);

当且仅当 $x 大于或等于 $y 时返回 true,否则返回 false。

blsft()/brsft()

用于将数字左/右移位。

有关更多详细信息,请参阅 Math::BigInt 中的文档。

band()
$x->band($y);               # bitwise and
bior()
$x->bior($y);               # bitwise inclusive or
bxor()
$x->bxor($y);               # bitwise exclusive or
bnot()
$x->bnot();                 # bitwise not (two's complement)
bpow()
$x->bpow($y);

计算 $x ** $y。

有关更多详细信息,请参阅 Math::BigInt 中的文档。

blog()
$x->blog($base, $accuracy);         # logarithm of x to the base $base

如果未定义 $base,则使用欧拉数 (e)

print $x->blog(undef, 100);         # log(x) to 100 digits
bexp()
$x->bexp($accuracy);        # calculate e ** X

计算两个整数 A 和 B,使得 A/B 等于 e ** $x,其中 e 是欧拉数。

此方法在 Math::BigRat 的 v0.20 版本(2007 年 5 月)中添加。

另请参阅 blog()

bnok()
$x->bnok($y);               # x over y (binomial coefficient n over k)

计算二项式系数 n 除以 k,也称为“选择”函数。结果等效于

( n )      n!
| - |  = -------
( k )    k!(n-k)!

此方法在 Math::BigRat 的 v0.20 版本(2007 年 5 月)中添加。

config()
Math::BigRat->config("trap_nan" => 1);      # set
$accu = Math::BigRat->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 div, sqrt etc.
                        40
trap_nan        RW      Trap NaNs
                        undef
trap_inf        RW      Trap +inf/-inf
                        undef

数值字面量

use Math::BigRat ':constant' 之后,给定范围内的所有数值字面量都将转换为 Math::BigRat 对象。此转换在编译时发生。每个非整数都将转换为 NaN。

例如,

perl -MMath::BigRat=:constant -le 'print 2**150'

打印 2**150 的精确值。请注意,如果没有将常量转换为对象,则表达式 2**150 将使用 Perl 标量进行计算,这会导致结果不准确。

请注意,字符串不受影响,因此

use Math::BigRat qw/:constant/;

$x = "1234567890123456789012345678901234567890"
        + "123456789123456789";

确实为您提供了您期望的结果。您需要在至少一个操作数周围显式使用 Math::BigRat->new()。您还应该引用大型常量以防止精度丢失

use Math::BigRat;

$x = Math::BigRat->new("1234567889123456789123456789123456789");

如果没有引号,Perl 首先在编译时将大数转换为浮点常量,然后在运行时将结果转换为 Math::BigRat 对象,这会导致结果不准确。

十六进制、八进制和二进制浮点字面量

Perl(以及此模块)接受十六进制、八进制和二进制浮点字面量,但在 Perl 版本低于 v5.32.0 时谨慎使用,因为某些版本的 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

错误

请将任何错误或功能请求报告到 bug-math-bigrat at rt.cpan.org,或通过网页界面报告到 https://rt.cpan.org/Ticket/Create.html?Queue=Math-BigRat(需要登录)。我们会收到通知,然后您会在我对错误进行更改时自动收到进度通知。

支持

您可以使用 perldoc 命令查找此模块的文档。

perldoc Math::BigRat

您也可以在以下位置查找信息:

许可证

本程序是自由软件;您可以在与 Perl 本身相同的条款下重新发布和/或修改它。

另请参阅

bigratMath::BigFloatMath::BigInt 以及后端 Math::BigInt::FastCalcMath::BigInt::GMPMath::BigInt::Pari

作者