1

16 進数値 0x78 があるとします。最初の 4 ビット、つまり 3:0 に 1 を追加し、最後の 4 ビットに 2 を追加する必要があります。[7:4]。さらに、0xF に 1 を追加すると、次の値にロールオーバーせず、0xF のままにする必要があります。減算についても同様です。これまでに試したアプローチは次のとおりです。

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

--> ここでは出力が 1000 なので、最初の 4 ビットを抽出しようとしました。同様に、右シフトして最後の 4 ビットを抽出し、演算を実行できます。しかし、加算または減算を実行するには、0x8 +/- 1 を実行できるように、1000 を 16 進数形式に変換したいと考えていました。そのために、次のことを試しました。

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

--> 出力は 3e8 です。16 進形式で 2 つの値のみを出力することになっているため、8 または 08 ではなく 3e8 を取得する理由がわかりません。

上記のコマンドで手動で $hex2 = sprintf('%02x', 0b1000); と入力すると、正しい結果が得られます。したがって、perl はこれを数値ではなく文字列と見なしています。その文字列を 2 進数に変換する方法はありますか? 他のより簡単な方法またはアプローチが役立ちます。

4

3 に答える 3

1

AND とシフトによって各バイトを取得できます。

$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

$byte2 が '1000' であるため、'3e8' を取得しています。16 進数に変換すると '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 に答える