内容

名称

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 或精度

这会为所有数学运算设置精度。参数可以是任意整数。负值表示小数点后固定位数,而正值表示从点向左舍入到此位数。0 表示舍入为整数。有关详细信息,请参阅 Math::BigInt 的 bfround() 方法。

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

请注意,同时设置精度和准确度是不可能的。

t 或跟踪

这会启用跟踪模式,主要用于调试。

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 或版本

这会打印模块的名称和版本,然后退出。

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 用可以处理大整数值的新版本覆盖这些例程。然而,在低于 v5.9.4 版本的 Perl 中,除非您使用两个导入标记“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 上的 Web 界面(需要登录)报告。我们会收到通知,然后当我对错误进行更改时,您会自动收到错误进度通知。

支持

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

perldoc bigrat

您还可以在以下位置查找信息

许可证

此程序是免费软件;您可以在与 Perl 本身相同的条款下重新分发或修改它。

另请参阅

bignumbigint

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

作者