在Windows 32位平台上,我必须读取一些数字,这是出乎意料的,其值可以高达99,999,999,999,但不能超过。尝试将其sprintf("%011d", $myNum)
输出上溢:-2147483648。
我无法使用BigInt模块,因为在这种情况下,我应该深刻地更改代码。我无法将格式作为字符串sprintf("%011s", $numero)
进行管理,因为负号处理不正确。
我该如何处理?装箱/拆箱会有所帮助吗?
尝试将其格式化为没有小数部分的浮点数:
$ perl -v
This is perl, v5.6.1 built for sun4-solaris
...
$ perl -e 'printf "%011d\n", 99999999999'
-0000000001
$ perl -e 'printf "%011.0f\n", 99999999999'
99999999999
是的,Perl的数字盲点之一是格式化; Perl自动将数字表示为整数或很好地进行浮点处理,然后将其强制转换为使用printf
数字格式时,即使没有使用适当。而且printf
根本无法处理BigInts(除非通过将它们转换为字符串,然后将其转换为数字,但会降低精度)。
使用%s而不是%d来确定您认为合适的任何数字范围是一个很好的解决方法,除非您注意负数。处理这些,您将不得不编写一些Perl代码。
我不是Perl专家,也许我在这里缺少对bignums的某种自动处理,但这不是整数溢出的情况吗? 32位整数不能容纳最大为99,999,999,999的数字。
无论如何,我在32位Linux机器上使用Perl v5.8.8可获得相同的结果,并且似乎带有“%d”的printf无法处理更大的数字。
我认为您的Perl副本必须被破坏,这是来自CygWin的版本(5.10):
pax$ perl -e 'printf("%011d\n", 99999999999);'
99999999999
pax$ perl -v
This is perl, v5.10.0 built for cygwin-thread-multi-64int
(with 6 registered patches, see perl -V for more detail)
Copyright 1987-2007, Larry Wall
Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.
Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl". If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.
您正在运行什么版本(perl -v
的输出?
您可能需要获得启用了Perl的64位版本[可能还有一台新的64位生产机](请注意我的输出中的"cygwin-thread-multi-64int"
)。这样至少可以避免更改代码的需要。
我是根据您不想大幅度更改代码(即您担心会破坏代码)来说明这一点的。新硬件的解决方案虽然有点贵,但几乎可以肯定不需要您更改软件。这取决于您的优先级。[另一种可能性是Perl本身可能正确存储了该数字,但由于printf()
错误,因此显示错误。在这种情况下,您可能需要尝试:
$million = 1000000;
$bignum = 99999999999;
$firstbit = int($bignum / $million);
$secondbit = $bignum - $firstbit * million;
printf ("%d%06d\n",$firstbit,$secondbit);
将其放入函数并调用该函数以返回字符串,例如:
sub big_honkin_number($) {
$million = 1_000_000;
$bignum = shift;
$firstbit = int($bignum / $million);
$secondbit = $bignum - $firstbit * $million;
return sprintf("%d%06d\n", $firstbit, $secondbit);
}
printf ("%s", big_honkin_number (99_999_999_999));
请注意,我在64位平台上进行了此测试-您需要在32位平台上进行自己的测试,但是您可以使用任何想要的缩放因子(如果需要,可以包括两个以上的段)。
更新:
big_honkin_number()
技巧在32位Perl上可以正常工作,因此看起来像[[is,只是printf()
函数正在使您烦恼:pax@pax-desktop:~$ perl -v
This is perl, v5.8.8 built for i486-linux-gnu-thread-multi
Copyright 1987-2006, Larry Wall
Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.
Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl". If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.
pax@pax-desktop:~$ perl qq.pl
99999999999