Perl:将MSB和其余位从十六进制中分离出来

时间:2017-08-31 04:57:33

标签: perl

我需要将二进制字符串中的MSB和其余位分开。例如:我有一个十六进制字符串a2,相当于1010 0010。我想分离出MSB(在这种情况下为1),其余的数字转换为十进制。我想我可以这样做:

$hex = 'a2';
$dec = hex($hex);
$bin = sprintf("%b", $dec);
$msb = substr $bin, 0, 1;
$rest = substr $bin 1, 7;

$restDec = oct("0b" . $rest);

但是,我不喜欢使用字符串进行位操作。有没有更好的方法呢?

1 个答案:

答案 0 :(得分:6)

使用按位运算符的简单:

$msb  = ($dec & 128) >> 7
$rest = ($dec & 127)

说明:

十进制128是0x800b1000_0000,因此使用按位"和"除了顶部位之外的所有操作符都有128个掩码(设置为零),然后我们向下移动到结果最终为0或1的LSB。实际上,您可以省去屏蔽操作并向右移动但是显式屏蔽已经两个好处:

  1. 它使意图清晰,
  2. 即使您无意中将其应用于大于255的数字也能正常工作。
  3. 十进制127是0x7F0b0111_1111和按位"和 - "使用$dec将MSB设置为零,而将其余部分单独保留。

    附加说明:Perl有十六进制数字文字(0x...二进制文字(0b...),所以上面也可以写成

    $msb  = ($dec & 0x80) >> 7
    $rest = ($dec & 0x7F)
    

    甚至

    $msb  = ($dec & 0b10000000) >> 7
    $rest = ($dec & 0b01111111)