bigfloat - Perl 透明大浮点数支持
use bigfloat;
$x = 2 + 4.5; # Math::BigFloat 6.5
print 2 ** 512 * 0.1; # Math::BigFloat 134...09.6
print inf + 42; # Math::BigFloat inf
print NaN * 7; # Math::BigFloat NaN
print hex("0x1234567890123490"); # Perl v5.10.0 or later
{
no bigfloat;
print 2 ** 256; # a normal Perl scalar now
}
# for older Perls, import into current package:
use bigfloat qw/hex oct/;
print hex("0x1234567890123490");
print oct("01234567890123490");
给定作用域中的所有数字字面量都将转换为 Math::BigFloat 对象。
所有运算符(包括基本数学运算)除了范围运算符 ..
都被重载。
因此,以下代码
use bigfloat;
$x = 1234;
创建一个 Math::BigFloat 并将对它的引用存储在 $x 中。这在幕后透明地发生。
您可以使用以下代码查看这一点
perl -Mbigfloat -le 'print ref(1234)'
由于数字实际上是对象,因此您可以对它们调用 Math::BigFloat 中的所有常用方法。这在一定程度上也适用于表达式
perl -Mbigfloat -le '$x = 1234; print $x->bdec()'
perl -Mbigfloat -le 'print 1234->copy()->binc();'
perl -Mbigfloat -le 'print 1234->copy()->binc->badd(6);'
perl -Mbigfloat -le 'print +(1234)->copy()->binc()'
(请注意,如果表达式以 '(' 开头,print 的行为与预期不符,因此需要使用 +
)
您甚至可以像往常一样将操作链接在一起
perl -Mbigfloat -le 'print 1234->copy()->binc->badd(6);'
1241
请注意,以下代码无法按预期工作(不输出任何内容),因为 Perl 中(截至 v5.8.0)尚不支持 '..' 的重载
perl -Mbigfloat -le 'for (1..2) { print ref($_); }'
bigfloat
识别一些选项,这些选项可以在通过 use
加载时传递。以下选项存在
这将设置所有数学运算的精度。参数必须大于或等于零。有关详细信息,请参阅 Math::BigInt 的 bround() 方法。
perl -Mbigfloat=a,50 -le 'print sqrt(20)'
请注意,无法同时设置精度和准确度。
这将设置所有数学运算的精度。参数可以是任何整数。负值表示小数点后固定位数,而正值表示四舍五入到小数点左侧的该位数。0 表示四舍五入到整数。有关详细信息,请参阅 Math::BigInt 的 bfround() 方法。
perl -Mbigfloat=p,-50 -le 'print sqrt(20)'
请注意,无法同时设置精度和准确度。
这将启用跟踪模式,主要用于调试。
加载不同的数学库,请参阅 "数学库"。
perl -Mbigfloat=l,GMP -e 'print 2 ** 512'
perl -Mbigfloat=lib,GMP -e 'print 2 ** 512'
perl -Mbigfloat=try,GMP -e 'print 2 ** 512'
perl -Mbigfloat=only,GMP -e 'print 2 ** 512'
用可以处理大数字的版本覆盖内置的 hex() 方法。这通过将其导出到当前包来覆盖它。在 Perl v5.10.0 及更高版本中,这并不那么必要,因为只要 bigfloat
准则处于活动状态,hex() 就会在当前范围内进行词法覆盖。
用可以处理大数字的版本覆盖内置的 oct() 方法。这通过将其导出到当前包来覆盖它。在 Perl v5.10.0 及更高版本中,这并不那么必要,因为只要 bigfloat
准则处于活动状态,oct() 就会在当前范围内进行词法覆盖。
这将打印出模块的名称和版本,然后退出。
perl -Mbigfloat=v
数字的数学运算(默认情况下)由名为 Math::BigInt::Calc 的后端库模块完成。默认值等效于以下语句
use bigfloat lib => 'Calc';
您可以使用以下语句更改此设置
use bigfloat lib => 'GMP';
以下代码将首先尝试查找 Math::BigInt::Foo,然后查找 Math::BigInt::Bar,如果这两个库都找不到,则恢复到 Math::BigInt::Calc
use bigfloat lib => 'Foo,Math::BigInt::Bar';
使用 c<lib> 会在找不到任何指定的库并且 Math::BigInt 回退到默认库之一时发出警告。要抑制此警告,请使用 c<try> 代替
use bigfloat try => 'GMP';
如果您希望代码直接终止而不是回退,请使用only
代替。
use bigfloat only => 'GMP';
有关更多详细信息,请参阅相应模块文档。
由于所有数字现在都是对象,因此您可以使用 Math::BigFloat 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 中的更多详细信息,请参阅文档。
返回 Math::BigFloat->binf() 的快捷方式。由于 Perl 并不总是正确处理裸字inf
,因此很有用。
返回 Math::BigFloat->bnan() 的快捷方式。由于 Perl 并不总是正确处理裸字NaN
,因此很有用。
# perl -Mbigfloat=e -wle 'print e'
返回欧拉数e
,也称为 exp(1)
# perl -Mbigfloat=PI -wle 'print PI'
返回 PI。
bexp($power, $accuracy);
返回欧拉数e
乘以适当的幂,达到所需的精度。
示例
# perl -Mbigfloat=bexp -wle 'print bexp(1,80)'
bpi($accuracy);
返回 PI,达到所需的精度。
示例
# perl -Mbigfloat=bpi -wle 'print bpi(80)'
设置或获取精度。
设置或获取精度。
设置或获取舍入模式。
设置或获取除法比例。
设置或获取降级类升级到的类(如果有)。将升级类设置为undef
以禁用升级。
默认情况下,升级被禁用。
设置或获取升级类降级到的类(如果有)。将降级类设置为undef
以禁用降级。
默认情况下,降级被禁用。
use bigfloat;
print "in effect\n" if bigfloat::in_effect; # true
{
no bigfloat;
print "in effect\n" if bigfloat::in_effect; # false
}
返回当前作用域中是否启用了bigfloat
。
此方法仅适用于 Perl v5.9.4 或更高版本。
Perl(以及此模块)接受十六进制、八进制和二进制浮点数字面量,但在 Perl 版本低于 v5.32.0 时谨慎使用,因为某些版本的 Perl 会静默地给出错误的结果。
bigrat
通过重载整数和浮点数字面量的处理方式来工作,将它们转换为 Math::BigRat 对象。
这意味着仅涉及字符串值或字符串字面量的算术运算将使用 Perl 的内置运算符执行。
例如
use bigrat;
my $x = "900000000000000009";
my $y = "900000000000000007";
print $x - $y;
在默认的 32 位构建中输出0
,因为bigfloat
永远不会看到字符串字面量。为了确保表达式中的所有内容都被视为Math::BigFloat
对象,请在表达式中使用字面量数字
print +(0+$x) - $y;
Perl 不允许重载范围,因此您既不能安全地使用具有bigfloat
端点的范围,也不能将迭代器变量设置为Math::BigFloat
。
use 5.010;
for my $i (12..13) {
for my $j (20..21) {
say $i ** $j; # produces a floating-point number,
# not an object
}
}
此方法仅适用于 Perl v5.9.4 或更高版本。
bigfloat
使用可以处理大整数的版本覆盖了这些例程。然而,在 Perl 版本低于 v5.9.4 的情况下,除非您使用两个导入标签“hex”和“oct”明确要求,否则这种情况不会发生——并且它将是全局的,无法在使用no bigfloat
的作用域内禁用。
use bigfloat qw/hex oct/;
print hex("0x1234567890123456");
{
no bigfloat;
print hex("0x1234567890123456");
}
对 hex() 的第二次调用将警告非可移植常量。
将此与以下内容进行比较
use bigfloat;
# will warn only under Perl older than v5.9.4
print hex("0x1234567890123456");
一些酷炫的命令行示例,让 Python 用户印象深刻;)
perl -Mbigfloat -le 'print sqrt(33)'
perl -Mbigfloat -le 'print 2**255'
perl -Mbigfloat -le 'print 4.5+2**255'
perl -Mbigfloat -le 'print 3/7 + 5/7 + 8/3'
perl -Mbigfloat -le 'print 123->is_odd()'
perl -Mbigfloat -le 'print log(2)'
perl -Mbigfloat -le 'print exp(1)'
perl -Mbigfloat -le 'print 2 ** 0.5'
perl -Mbigfloat=a,65 -le 'print 2 ** 0.2'
perl -Mbigfloat=l,GMP -le 'print 7 ** 7777'
请将任何错误或功能请求报告给bug-bignum at rt.cpan.org
,或通过网页界面报告给 https://rt.cpan.org/Ticket/Create.html?Queue=bignum(需要登录)。我们会收到通知,然后您会在我对错误进行更改时自动收到进度通知。
您可以使用 perldoc 命令查找此模块的文档。
perldoc bigfloat
您也可以在以下位置查找信息:
GitHub
RT:CPAN 的请求跟踪器
MetaCPAN
CPAN 测试者矩阵
CPAN 评级
本程序是自由软件;您可以根据与 Perl 本身相同的条款重新发布和/或修改它。
Math::BigInt、Math::BigFloat、Math::BigRat 和 Math::Big 以及 Math::BigInt::FastCalc、Math::BigInt::Pari 和 Math::BigInt::GMP。
由 Tels 于 2002 年初至 2007 年创建 (C) http://bloodgate.com/。
由 Peter John Acklam <[email protected]> 于 2014 年起维护。