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

Kam*_*han 3 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);
Run Code Online (Sandbox Code Playgroud)

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

Jim*_*son 6

使用按位运算符的琐碎:

$msb  = ($dec & 128) >> 7
$rest = ($dec & 127)
Run Code Online (Sandbox Code Playgroud)

说明:

十进制128是0x80或者0b1000_0000,因此使用带有128个掩码(设置为零)的按位"和"运算符除了顶部位之外的所有位置,然后我们向下移动到LSB,结果最终为0或1.实际上,您可以分配使用屏蔽操作并向右移动但显式屏蔽有两个优点:

  1. 它使意图清晰,并且
  2. 即使您无意中将此应用于大于255的数字也能正常工作.

十进制127是0x7F或者0b0111_1111按位"和"这一$dec点将MSB设置为零,而单独留下其余的位.

附加说明:Perl具有十六进制数字文字(0x...)二进制文字(0b...),因此也可以编写上述内容

$msb  = ($dec & 0x80) >> 7
$rest = ($dec & 0x7F)
Run Code Online (Sandbox Code Playgroud)

甚至

$msb  = ($dec & 0b10000000) >> 7
$rest = ($dec & 0b01111111)
Run Code Online (Sandbox Code Playgroud)