我有一个大的十六进制数 - $num = 0x80000000
,作为一个字符串。我想增加它,但hex($num)
由于整数溢出(结果为负),这样做不起作用。usingbigint
也不是一个选项,因为带有 bigint 的十六进制仅在 perl 5.10 及更高版本中实现,我有 5.8。我怎样才能++这个字符串?
2 回答
不要将文字表示与带有实际值的数字混淆。当您进行分配时,无论您如何表示它,Perl 最终都会存储一个数字并且不再关心原始表示。对它使用正常的数字运算。当你想再看一遍时,你可以选择任何你喜欢的表示:
$num = 0x8000000;
$num++;
printf "%0x" $num;
仅hex()
当您将数字表示形式作为字符串获取时才需要,就像从命令行参数中获取的一样。您只需hex
要将字符串转换为数字即可。在那之后,它是一样的。
$num = hex( '8000000' ); # or hex( '0x8000000' )
# $num = hex( $ARGV[0] );
$num++;
printf "%0x" $num;
对于您问题的另一部分,bignum
在 Perl v5.8 上工作得很好:
$ perl5.8.9 -le 'my $i = 0xFFFFFFFF_FFFFFFFF; $i++; print $i'
1.84467440737096e+19
$ perl5.8.9 -Mbignum -le 'my $i = 0xFFFFFFFF_FFFFFFFF; $i++; print $i'
18446744073709551616
我通过Perlbrew使用 Perl 5.8.9 对此没有任何问题:
#! /usr/bin/env perl
use strict;
use warnings;
my $num = 0x80000000;
print "$num\n"; # No quotes make this a number and not a string
这打印出2147483648
哪个是 的十进制值0x8000000
。
你在哪个平台?
您可能想要做的是以十六进制而不是十进制打印出这个十六进制数。您仍然可以使用++
它来增加它,但是要以十六进制打印出来,您需要printf:
#! /usr/bin/env perl
#
use strict;
use warnings;
use Data::Dumper;
my $num = 0x80000000;
for my $loop (0..100) {
$num++;
printf "%-20x\n", $num;
}
这打印出来:
80000001
80000002
80000003
80000004
80000005
80000006
80000007
80000008
80000009
8000000a
...
如果确实0x80000000
是一个字符串,在我使用 Perl 5.8.9 的系统上使用十六进制将其转换为数字没有问题。
#! /usr/bin/env perl
use strict;
use warnings;
my $num = "0x80000000"; # This is a string
$num = hex $num; # Now it's a number
print "$num\n"; # Prints 2147483648 because `$num` is numeric
就像我说的。这是 Perl 5.8.9(我无法在 Perlbrew 上获得 5.8.8),这是在 Mac 上。也许您的平台有点不同。它是带有 32 位版本 SunOS 或 Solaris 的旧 Solaris 系统吗?
我检查了 5.8.8 文档并注意到标准发行版确实内置了Bigint 支持。它也带有模块Math::Bigint。
你确定你没有 Bigint 支持吗?