如何进行64位十六进制/十进制算术并在HEX中输出一个完整的数字作
我需要用下面的大十六进制数做一些算术,但是当我尝试输出时我得到溢出错误消息“Hexadecimal number> 0xffffffff non-portable”,有关不可移植的消息,或者最大32位十六进制值FFFFFFFF .
所有这些都意味着标准语言和输出例程只能处理32位值.我需要64位值,并做了很多研究,但我没有发现BOTH启用算术AND以十六进制输出大数字. my $result = 0x00000200A0000000 + ( ( $id & 0xFFFFF ) * 2 ) + ( ( $id / 0x100000 ) * 0x40000000 ); 所以,对于带有以下值的$id,我应该得到$result: $id = 0,$result = 0x00000200A0000000 $id = 1,$result = 0x00000200A0000002 $id = 2,$result = 0x00000200A0000004 我怎样才能做到这一点? 以下是我不确定的研究结果,原因如下: > How can I do 64-bit arithmetic in Perl? 编辑:更新 – 新要求和提供的解决方案 – 请随时提供评论 查斯.欧文斯的答案仍然被接受和优秀(第2部分对我有效,没有尝试过新的Perl的第1部分版本,尽管我会邀请其他人确认). 但是,另一个要求是能够从结果转换回原始id. 所以我写了代码来做这个,这是完整的解决方案,包括@Chas.欧文斯原始解决方案,然后实施这一新要求: #!/usr/bin/perl use strict; use warnings; use bigint; use Carp; sub bighex { my $hex = shift; my $part = qr/[0-9a-fA-F]{8}/; croak "$hex is not a 64-bit hex number" unless my ($high,$low) = $hex =~ /^0x($part)($part)$/; return hex("0x$low") + (hex("0x$high") << 32); } sub to_bighex { my $decimal = shift; croak "$decimal is not an unsigned integer" unless $decimal =~ /^[0-9]+$/; my $high = $decimal >> 32; my $low = $decimal & 0xFFFFFFFF; return sprintf("%08x%08x",$high,$low); } for my $id (0,1,2,0xFFFFF,0x100000,0x100001,0x1FFFFF,0x200000,0x7FDFFFFF ) { my $result = bighex("0x00000200A0000000"); $result += ( ( $id & 0xFFFFF ) * 2 ) + ( ( $id / 0x100000 ) * 0x40000000 ); my $clusterid = to_bighex($result); # the convert back code here: my $clusterid_asHex = bighex("0x".$clusterid); my $offset = $clusterid_asHex - bighex("0x00000200A0000000"); my $index_small_units = ( $offset / 2 ) & 0xFFFFF; my $index_0x100000_units = ( $offset / 0x40000000 ) * 0x100000; my $index = $index_0x100000_units + $index_small_units; print "$id = ".to_bighex( $id ). " clusterid = ".$clusterid. " back to $id = ".to_bighex( $index ). " n"; } 请在http://ideone.com/IMsp6试用此代码. 解决方法#!/usr/bin/perl use strict; use warnings; use bigint qw/hex/; for my $id (0,2) { my $result = hex("0x00000200A0000000") + ( ( $id & 0xFFFFF ) * 2 ) + ( ( $id / 0x100000 ) * 0x40000000 ); printf "%d: %#016xn",$id,$result; }
注意,这仅适用于Perl 5.10及更高版本.如果您运行的是早期版本的Perl 5,可以尝试这样做: #!/usr/bin/perl use strict; use warnings; use bigint; use Carp; sub bighex { my $hex = shift; my $part = qr/[0-9a-fA-F]{8}/; croak "$hex is not a 64-bit hex number" unless my ($high,2) { my $result = bighex("0x00000200A0000000"); $result += ( ( $id & 0xFFFFF ) * 2 ) + ( ( $id / 0x100000 ) * 0x40000000 ); print "$id ",to_bighex($result),"n"; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |