【问题标题】:How to isolate leftmost bytes in integer如何隔离整数中最左边的字节
【发布时间】:2019-07-30 03:52:22
【问题描述】:

这必须在 Perl 中完成:

我有整数,例如30_146_890_129 和 17_181_116_691 和 21_478_705_663。

这些应该由 6 个字节组成,其中:

  • 字节0-1:值a
  • 字节2-3:值b
  • 字节4-5:值c

我想隔离 a 是什么值。如何在 Perl 中做到这一点?

我尝试过使用>> 运算符:

perl -e '$a = 330971351478 >> 16; print "$a\n";'
5050222
perl -e '$a = 17181116691 >> 16; print "$a\n";'
262163

但这些数字并不是我所期望的顺序,更像是 0-1000。

如果我也可以得到值 bc ,那么我也可以得到奖励,但我真的不需要这些。

谢谢!

【问题讨论】:

    标签: perl bit-manipulation


    【解决方案1】:

    number >> 16 返回 number 移位 16 位,而不是您似乎假设的移位位。例如,要获取最后 16 位,您可以使用 number % 2**16number & 0xffff。要获得bc,您可以在获得最后 16 位之前进行移位,即

    $a = $number & 0xffff;
    $b = ($number >> 16) & 0xffff;
    $c = ($number >> 32) & 0xffff;
    

    【讨论】:

      【解决方案2】:

      如果您有 6 个字节,则无需先将它们转换为数字。您可以根据字节的顺序使用以下之一:(大写表示最高有效字节。)

      my ($num_c, $num_b, $num_a) = unpack('nnn', "\xCC\xcc\xBB\xbb\xAA\xaa");
      my ($num_a, $num_b, $num_c) = unpack('nnn', "\xAA\xaa\xBB\xbb\xAA\xaa");
      my ($num_c, $num_b, $num_a) = unpack('vvv', "\xcc\xCC\xbb\xBB\xaa\xAA");
      my ($num_a, $num_b, $num_c) = unpack('vvv', "\xaa\xAA\xbb\xBB\xcc\xCC");
      

      如果确实为您提供了一个数字0xCCccBBbbAAaa),您可以将其转换为字节,然后从中提取您想要的数字,如下所示:

      my ($num_c, $num_b, $num_a) = unpack('xxnnn', pack('Q>', $num));
      

      或者,您也可以像尝试的那样使用算术方法。

      my $num_a =   $num         & 0xFFFF;
      my $num_b = ( $num >> 16 ) & 0xFFFF;
      my $num_c =   $num >> 32;
      

      虽然前两个解决方案需要 Perl built to use 64-bit integers,但以下解决方案适用于任何 Perl 构建:

      my $num_a =      $num           % 2**16;
      my $num_b =    ( $num / 2**16 ) % 2**16;
      my $num_c = int( $num / 2**32 );
      

      让我们详细看看( $num >> 16 ) & 0xFFFF

      Original number: 0x0000CCccBBbbAAaa
      After shifting:  0x00000000CCccBBbb
      After masking:   0x000000000000BBbb
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-11
        • 2021-10-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多