1

假设我有一个十六进制值 0x78。我需要将 1 添加到前 4 位,即 3:0,然后将 2 添加到最后 4 位,即。[7:4]。此外,当我将 1 添加到 0xF 时,它不应该翻转到下一个值,并且应该保持为 0xF。同样适用于减法。到目前为止我尝试过的方法是:

$byte=0x78;
$byte2 = unpack('b4', $byte);
print "byte2 = $byte2 \n";

--> 这里的输出是 1000,所以我尝试提取前 4 位,同样我可以右移并提取后 4 位并执行操作。但是要执行加法或减法,我想将 1000 转换回十六进制格式,以便可以执行 0x8 +/- 1。为此,我尝试了:

$hex2 = sprintf('%02x', $byte2);
print "hex2 = $hex2 \n";

--> 输出为 3e8。我不明白为什么我得到 3e8 而不是 8 或 08,因为它应该只打印 2 个十六进制格式的值。

在上面的命令中当我手动输入 $hex2 = sprintf('%02x', 0b1000); 我得到正确的结果。所以 perl 把它当作一个字符串而不是一个数值。有什么方法可以将该字符串转换为二进制数吗?任何其他更简单的方法或方法都会有所帮助。

4

3 回答 3

1

我们可以通过 ANDing 和 shift 得到每个字节:

$byte1 = $byte & 0xf;
$byte2 = ($byte & 0xf0) >> 4;
printf "byte1: 0x%x\n", $byte1;
printf "byte2: 0x%x\n", $byte2;

# prints
byte1: 0x8
byte2: 0x7

您列出的特殊条件的加法/减法可以在这些字节上完成,并且可以通过移位和加法重建新值:

($byte1 < 0xf) ? ($byte1 += 1) : ($byte1 = 0xf);
($byte2 < 0xe) ? ($byte2 += 2) : ($byte2 = 0xf);
# or do subtraction stuff.

$new_val = ($byte2 << 4) + $byte1;
printf "new val: 0x%x\n", $new_val;

# prints
new val: 0x99

你得到'3e8',因为$byte2 是'1000',当翻译成十六进制时是'0x3e8'。

于 2013-08-20T00:08:33.773 回答
0

我认为您最好使用以下方法:

sub byte_to_two_nibbles($) {
    my $byte = shift;
    return int($byte / 16), ($byte % 16);
}

sub two_nibbles_to_byte($$) {
    return $_[0] * 16 + $_[1];
}

my ($msn, $lsn) = byte_to_two_nibbles 0x78;
$msn += 1; $msn = 15 if $msn > 15;
$lsn += 2; $lsn = 15 if $lsn > 15;
my $result = two_nibbles_to_byte $msn, $lsn;
于 2013-08-19T23:18:49.753 回答
0

您可以使用oct函数:

$byte2 = oct("0b$byte2");
my $hex2 = sprintf('%02x', $byte2);
print "hex2 = $hex2 \n";

印刷:

hex2 = 08 
于 2013-08-19T23:25:39.267 回答