Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Perl中冲刺一个大数字?_Perl_Printf_Bignum - Fatal编程技术网

如何在Perl中冲刺一个大数字?

如何在Perl中冲刺一个大数字?,perl,printf,bignum,Perl,Printf,Bignum,在Windows 32位平台上,我必须读取一些数字,这些数字的值可以达到99999999999,但不能超过。试图sprintf(“%011d”,$myNum)它们输出一个溢出:-2147483648 我不能使用BigInt模块,因为在这种情况下,我应该深刻地修改代码。我无法将格式管理为字符串,sprintf(“%011s”,$numero),因为减号处理不正确 我该怎么办?打包/解包能帮点忙吗 我不是Perl专家,也许我在这里遗漏了一些bignum的自动处理,但这不是简单的整数溢出吗?32位整数

在Windows 32位平台上,我必须读取一些数字,这些数字的值可以达到99999999999,但不能超过。试图
sprintf(“%011d”,$myNum)
它们输出一个溢出:-2147483648

我不能使用BigInt模块,因为在这种情况下,我应该深刻地修改代码。我无法将格式管理为字符串,
sprintf(“%011s”,$numero)
,因为减号处理不正确


我该怎么办?打包/解包能帮点忙吗

我不是Perl专家,也许我在这里遗漏了一些bignum的自动处理,但这不是简单的整数溢出吗?32位整数不能容纳99999999这样大的数字


无论如何,我在32位Linux机器上使用Perl v5.8.8也得到了相同的结果,而且带“%d”的printf似乎不能处理更大的数字。

我认为您的Perl副本必须被破坏,这是CygWin的版本(5.10):

您正在运行哪个版本(perl-v的输出)

您可能需要获得一个支持64位的Perl版本[可能还需要一台新的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\u honkin\u number()
技巧在32位Perl上运行良好,因此看起来似乎正是
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

是的,Perl的数字盲点之一是格式化;Perl可以很好地将数字表示为整数或浮点数,但随后将它们强制为 当使用
printf
数字格式时,一种或另一种格式,即使不使用 适当的而且,
printf
根本不处理bigint(除了处理 将它们转换为字符串,并将其转换为数字,精度会降低)

将%s而不是%d与任何您不确定的数字一起使用将是适当的 范围是一个很好的解决方法,除非您注意到负数。处理
对于这些,您必须编写一些Perl代码。

尝试将其格式化为不含小数部分的浮点:

$ 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 -e "printf qq{%.0f\n}, 999999999999999"
999999999999999
但只是在一定程度上

perl -e "printf qq{%.0f\n}, 9999999999999999999999999999999999999999999999"
9999999999999998663747590131240811450955988992
Bignum在这里没有帮助

perl -e "use bignum ; printf qq{%.0f\n}, 9999999999999999999999999999999999999999999999"
9999999999999999931398190359470212947659194368    
问题是printf。(你真的需要printf吗?) 能打印吗

perl -e "use bignum;print 9999999999999999999999999999999999999999999999"
9999999999999999999999999999999999999999999999
话虽如此,perl的好处在于它始终是一个选择,您可以自行开发

e、 g


如果需要,我怀疑Perl会自动切换到Int64,但也没有Perl专家。不,在具有32位整数的Perl上,操作超出了整数切换到浮点的范围(通常是64位的
双精度
,虽然也可以是80位或128位的
长双精度
,但可以高达2^53,同时仍保持整数精度).bigint是一个库,它处理大于4字节/8字节整数的数字。实际上是任意大的。大小上的唯一限制是可用内存和CPU时间。问题是printf。您使用的是64位Perl,Daniel说他使用的是32位。在大多数情况下,即使没有64位处理器,您也可以构建64位Perl,因此硬件是l我完全不需要。我正在使用的版本:这是perl,v5.8.8,为MSWin32-x86-multi-thread构建(有25个注册补丁,请参阅perl-V了解更多详细信息)。无论如何,一行程序产生-0000000001。下载最新的CygWin并试一试。它可能会在32位CPU上处理64位数字,正如@ysth所建议的,那么你的问题就结束了。没有新机器,没有代码重写。sprintf是必要的吗?你能用手动格式将其输出为字符串吗?当然。我必须填写一个固定大小的字段(遗留代码…)我必须解决甚至是负数的问题。因此,在你看来,这并不是我对perl函数知识的缺乏?我将你的回答解释为:在格式化大数字时有一个特定的问题;你应该通过编写自己的例程来解决格式化问题。如果是这样的话,这当然是完全可以接受的演练。我怀疑的是忽略了一些ob这是答案,太好了。
perl -e "use bignum;print 9999999999999999999999999999999999999999999999"
9999999999999999999999999999999999999999999999
my $in = ...;
my $out = "";
while($in){
  my $chunk=$in & 0xf;
  $in >>= 4;
  $out = sprintf("%x",$chunk).$out;
}
print "0x$out\n";