我有一根绳子
$string = "0x0"
现在我想基本上使用这个字符串作为一个数字,并做一个按位移位,即我的目标是
$C = $string <<4 ;
但当我这样做时,它说:
Argument "0x0" isn't numeric in left bitshift (<<)
有没有人能帮我做这个?
y4ekin9u1#
这是因为“0x0”不是数字。它是一个字符串。你必须把它转换成一个数值。
use strict; use warnings; my $string = "0x0"; my $number = hex($string); my $C = $number <<4 ; print $C;
ubof19bj2#
如上所述,您必须将其转换为 numeric 值,并使用sprintf将其转换回 hexadecimal 值。
sprintf
sprintf ("0x%x" , hex($string) << 4);
jogvjijk3#
如果所需的移位已经是4的倍数,那么只需要将尾随的0 s填充到现有的十六进制中,而不是解码它然后重新sprintf()-ing它。
0
sprintf()
wnvonmuf4#
Perl通过查找前导符号字符、十进制数字或单个小数点将字符串转换为数字。当它遇到非十进制数字或第二个小数点时,它会停止。这也意味着前导0只是另一个十进制数字,而不是八进制指示符。由于b、o或x都不是这些字符,Perl在遇到它们时停止处理。
b
o
x
$ perl -le 'print 0 + shift' 0x37 0 $ perl -le 'print 0 + shift' 37 37 $ perl -le 'print 0 + shift' 1.2.3 1.2 $ perl -le 'print 0 + shift' -- -123fred -123
如果你的字符串有一个十六进制数,一个八进制数,或者一个二进制数,用Perl的内置函数转换它,告诉它要查找哪个基数:
一些示例(所有命令行参数都是字符串):
$ perl -le 'print hex(shift)' 0x37 55 $ perl -le 'print hex(shift)' 37 55 $ perl -le 'print hex(shift)' ab 171 $ perl -le 'print oct(shift)' 37 31 $ perl -le 'print oct(shift)' 037 31 $ perl -le 'print oct(shift)' 0o37 31
现在,还有另一个奇怪的特性。由于历史原因,今天完全不一致,oct函数识别所有前缀(包括octal prefix 0o added in v5.34):
0o
$ perl -le 'print oct(shift)' 0x37 55 $ perl -le 'print oct(shift)' 0o37 31 $ perl -le 'print oct(shift)' 0b111 7 $ perl -le 'print oct(shift)' 0123 83 $ perl -le 'print oct(shift)' 123 83
额外的好处是,核心Scalar::Util模块中的looks_like_number可以告诉你Perl认为什么是完全可识别的十进制数:
looks_like_number
$ perl -MScalar::Util -le 'print Scalar::Util::looks_like_number(shift) ? "Yes" : "No"' 0o37 No $ perl -MScalar::Util -le 'print Scalar::Util::looks_like_number(shift) ? "Yes" : "No"' 0x55 No $ perl -MScalar::Util -le 'print Scalar::Util::looks_like_number(shift) ? "Yes" : "No"' 137 Yes $ perl -MScalar::Util -le 'print Scalar::Util::looks_like_number(shift) ? "Yes" : "No"' 1.2.3 No $ perl -MScalar::Util -le 'print Scalar::Util::looks_like_number(shift) ? "Yes" : "No"' -- -1.2 Yes
4条答案
按热度按时间y4ekin9u1#
这是因为“0x0”不是数字。它是一个字符串。你必须把它转换成一个数值。
ubof19bj2#
如上所述,您必须将其转换为 numeric 值,并使用
sprintf
将其转换回 hexadecimal 值。jogvjijk3#
如果所需的移位已经是4的倍数,那么只需要将尾随的
0
s填充到现有的十六进制中,而不是解码它然后重新sprintf()
-ing它。wnvonmuf4#
Perl通过查找前导符号字符、十进制数字或单个小数点将字符串转换为数字。当它遇到非十进制数字或第二个小数点时,它会停止。这也意味着前导0只是另一个十进制数字,而不是八进制指示符。由于
b
、o
或x
都不是这些字符,Perl在遇到它们时停止处理。如果你的字符串有一个十六进制数,一个八进制数,或者一个二进制数,用Perl的内置函数转换它,告诉它要查找哪个基数:
一些示例(所有命令行参数都是字符串):
现在,还有另一个奇怪的特性。由于历史原因,今天完全不一致,oct函数识别所有前缀(包括octal prefix
0o
added in v5.34):额外的好处是,核心Scalar::Util模块中的
looks_like_number
可以告诉你Perl认为什么是完全可识别的十进制数: