Perl十六进制数的负数表示总是符号扩展到8字节
我在Perl中使用Perl十六进制数的负数表示总是符号扩展到8字节,perl,hex,printf,Perl,Hex,Printf,我在Perl中使用sprintf将十进制数转换为十六进制数,如下所示: my $positive = sprintf("X'%02X'", 1); # X'01' my $negative = sprintf("X'%02X'", -1); # X'FFFFFFFFFFFFFFFF' 为什么负数总是被符号扩展到数字的8字节表示形式,即使sprintf中指定的精度更小 有没有办法避免这种情况,这样我就不必每次都对值进行子串?即使我删除0,也会出现相同
sprintf
将十进制数转换为十六进制数,如下所示:
my $positive = sprintf("X'%02X'", 1); # X'01'
my $negative = sprintf("X'%02X'", -1); # X'FFFFFFFFFFFFFFFF'
为什么负数总是被符号扩展到数字的8字节表示形式,即使sprintf
中指定的精度更小
有没有办法避免这种情况,这样我就不必每次都对值进行子串?即使我删除
0
,也会出现相同的结果,如:sprintf(“X'%2X'”,-1)
好吧,%X
专门接受一个无符号整数,所以当你给它一个有符号整数的位模式时,它将所有这些位都视为一个无符号整数。输出的长度可能取决于编译器生成的数字有多大(尽管我猜现在大多数现代事物都是一样的)。Perl将其大部分数字存储为双倍,因此这就是数字的大小。这是Perl公开底层架构的少数几个地方之一
这意味着您需要自己处理符号并使用数字的绝对值:
sprintf( "%s%2x", ($n < 0 ? '-' : ''), abs($n) );
您希望为值-1生成哪些确切字符?我希望得到精度为2的
FF
(最终结果为X'FF'
),但正如Brian解释的那样,%X
需要一个无符号整数。我相信OP需要sprintf(“X'%02X',$n&0xFF)
,当负数的数量级大于遮罩时,这会中断。谢谢你们@ikegami是的,理想情况下,我希望它只是X'FF'
,没有实际符号。正如Brian所提到的,在某些条件下,它确实会中断,因此我可以随意处理它,或者根据需要将sprintf
返回的值作为子字符串。这没什么大不了的,因为这只是我编写的一个小脚本,用于生成值不会改变的表。@briandfoy,但我不认为它们的输入超出了-128..127。谁的输出?OP或者世界上任何一个读到这篇文章试图解决另一个问题的人?
my $s = sprintf( "%2x", $n );
$s = substr( $s, -2 ) if $n < 0;