【问题标题】:Linux Perl - Convertion of Hex Value to DecimalLinux Perl - 将十六进制值转换为十进制
【发布时间】:2020-10-01 09:01:35
【问题描述】:

我正在开发一个脚本,将收集的 HEX(我不知道它们的位格式)值转换为十进制值。

其中一个例子是十六进制值:fef306da 如果我转换它,我会收到 4277339866。

我找到预期值的网站(带符号 2 的补码的十进制:): https://www.rapidtables.com/convert/number/hex-to-decimal.html

你们有一个解决方案如何将十六进制 fef306da 转换为十进制 -17627430。 注意:当我转换十进制时有(-)负号的十六进制时,我得到错误的值转换。

谢谢大家!

【问题讨论】:

    标签: linux perl hex decimal


    【解决方案1】:

    查看pack 并对无符号和有符号值使用修饰符。

    my $hex_value = "fef306da";
    my $output_num = unpack('l', pack('L', hex($hex_value)));
    print $output_num; ## -17627430
    

    对每个十六进制值执行测试以确定它是 16 位还是 32 位值。 然后将正确的修饰符与 pack 一起用于长值或短值。

    【讨论】:

    • 非常感谢您的解释!你们两个救了我的命。我希望我以前知道。碰巧这是我第一次搞乱不同的十六进制到十进制转换.. ^_^ 顺便说一句.. 你的 $output_num 必须是你的 $num? XD 再次感谢!
    • 对其进行了排序 - 很高兴它对您有所帮助。 pack 是很有价值的工具。
    【解决方案2】:

    您似乎希望您的小数是 32 位有符号整数,但 HEX($n) 返回一个 64 位 所以你可以尝试重新包装它

    perl -e 'print unpack "l", pack "L", hex( "fef306da" )'
    

    【讨论】:

    • 非常感谢迈克!我很感激! :D
    【解决方案3】:

    你可以使用pack

    my $hex = "fef306da";
    my $num = hex($hex);
    $num = unpack("l", pack("L", $num));
    say $num;  # -17627430
    

    my $hex = "fef306da";
    $hex = substr("00000000$hex", -8);   # Pad to 8 chars
    my $num = unpack("l>", pack("H8", $hex));
    say $num;  # -17627430
    

    但是简单的算术就可以了。

    my $hex = "fef306da";
    my $num = hex($hex);
    $num -= 0x1_0000_0000 if $num >= 0x8000_0000;
    say $num;  # -17627430
    

    【讨论】:

      【解决方案4】:

      如果您对二进制转换感兴趣,请查看以下代码(fef306da 是 32 位数字)

      use strict;
      use warnings;
      use feature 'say';
      
      my $input   = 'fef306da';
      my $hex     = hex($input);
      my $dec;
      
      if( $hex & 0x80000000 ) {
         $dec = -1 * ((~$hex & 0x7fffffff)+1);
      } else {
         $dec = $data;
      }
      
      say $dec;
      

      输出

      -17627430
      

      提示:Two's complement

      【讨论】:

      • 提示:使用更好的变量名。 $hex 不包含任何十六进制。另外,-1 * ((~$num & 0x7fffffff)+1) 可以简化为0x1_0000_0000 - $num
      • @ikegami -- 我同意它应该是$raw,但是对于没有二进制数学经验的人来说,来自十六进制值的导数会更容易理解。我需要 imprint 在我的大脑中 0x1_0000_0000-$num 作为替代 - 现在看 binary operation 它变得非常明显,不知何故我没有想到为什么会有 +1.
      猜你喜欢
      • 2014-02-05
      • 1970-01-01
      • 1970-01-01
      • 2011-07-28
      • 1970-01-01
      • 2011-08-04
      相关资源
      最近更新 更多