【问题标题】:Working with 64-bit ints and hexes in 32-bit perl在 32 位 perl 中使用 64 位整数和十六进制
【发布时间】:2023-03-11 15:43:01
【问题描述】:

我想编写一个 perl 脚本来解析包含大量 64 位整数的文本文件。所有整数都用十六进制写。

我需要

  • 从输入中读取十六进制
  • 比较 64 位整数(<=>
  • 减去 64 位整数
  • 输出 64 位十六进制数

我需要使用 32 位 perl,我不能使用任何 CPAN/外部模块(脚本必须是可移植的)。

PS 我的 perl 是 5.8(这是用于脚本的最小版本)

PPS bignum/bigint 错误:

$ perl -e 'use bignum; $_=hex("0x0000123412345678")'
Integer overflow in hexadecimal number at -e line 1.

$ perl -e 'use bigint; $_=hex("0x0000123412345678")'
Integer overflow in hexadecimal number at -e line 1.

PPPS:这里没有from_hex

$ perl -e 'use Math::BigInt; $_=Math::BigInt->from_hex("0x0000123412345678");'
Can't locate object method "from_hex" via package "Math::BigInt" at -e line 1.

没有qw/hex/

$ perl -e 'use bigint qw/hex/; $_=hex("0x0000123412345678")'
unknown option hex at /usr/lib/perl5/5.8/bigint.pm line...

PPPPS:但 new() 有效:

$ perl -e 'use Math::BigInt; $_=Math::BigInt->new("0x0000123412345678"); print  $_->as_hex(),"\n";'
0x123412345678

【问题讨论】:

  • 根据更新中的错误。 hex 函数仅在 perl 5.9.4 或更高版本中由 bignum 自动升级。您需要显式导出 hex 函数(在您的 perl 版本中将是全局函数)或直接使用 Math::BigInt->from_hex(...) 函数。

标签: perl 64-bit hex


【解决方案1】:

核心编译指示bigint 将让您透明地处理大于系统支持的整数。 Math::BigInt 核心库中有相关的函数可以转换为十六进制表示。

【讨论】:

  • 当我尝试使用“use bignum;”时,出现“十六进制整数溢出”
  • 编译指示可能引入了太多的魔法,并且可能会破坏您的一些常量。尝试直接使用Math::BigInt->new(...) 构造函数。
  • Math::BigInt->new 将如何设置标志?
【解决方案2】:

Math::Int64 允许访问本机有符号和无符号 64 位数字。这肯定比可能的替代方案Math::BigInt 更快。

它有十六进制转换例程,它重载了比较和算术运算符,所以它可以做你要求的一切。

use Math::Int64 qw( hex_to_uint64 uint64_to_hex );
my $n1 = hex_to_uint64("200000000");
my $n2 = hex_to_uint64("300000000");
printf("n1 is %s equal to n2\n",     $n1 == $n2 ? "" : "not");
printf("n1 is %s less than n2\n",    $n1 <  $n2 ? "" : "not");
printf("n1 is %s greater than n2\n", $n1 >  $n2 ? "" : "not");
printf("0x%016s", uint64_to_hex($n2 - $n1));

输出:

n1 is not equal to n2
n1 is less than n2
n1 is not greater than n2
0x0000000100000000

使用或缺少 CPAN 不会影响脚本的可移植性。

【讨论】:

  • 错误是“$ perl -e 'use Math::Int64; ' Can't locate Math/Int64.pm in @INC”。正如问题所说,我不能使用 CPAN。
  • @osgx,不,您说出于可移植性原因不能使用 CPAN,witch 本质上是错误的。
  • 在我的情况下,目标 PC 根本没有 CPAN(和互联网)访问权限,并且很难安装一些新模块(目标 PC 上没有编译器,因为它是嵌入的;但上面有一个 perl 5.8)。我可以带一个 perl 脚本,它不会使用 XS/C。
  • @osgx,这不是可移植性问题,但它确实使 Math::BigInt 成为您更好的答案。 (请注意,我实际上并不知道 Math::Int64 的可移植性如何,因此实际上可能存在可移植性问题。)
  • 我的意思是有点不寻常的便携性。目标不是 x86/x86_64,因此它与 win/lin/mac 和 gcc/llvm/icc 之间通常的桌面/笔记本可移植性无关。对于我的情况,大多数 C 代码都不是很便携。我也不知道这一点,但是最后有评论说要增加对mingw32/win的支持,所以我认为它对我来说确实是不可移植的)
猜你喜欢
  • 1970-01-01
  • 2011-04-30
  • 2015-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-21
  • 1970-01-01
相关资源
最近更新 更多