我是Perl的新手,我在使用不同类型时遇到了困难。
我试图获得一个十六进制寄存器,将其转换为二进制,使用它一个字符串,并从二进制字符串中获取子串。
我做了一些搜索,我尝试的是:
my $hex = 0xFA1F;
print "$hex\n";
结果是“64031”。第一个惊喜:我不能在Perl中打印十六进制值而不仅仅是十进制值?
$hex = hex($hex);
print "$hex\n";
结果是409649.第二个惊喜:我希望结果也是64031,因为“hex”将十六进制转换为十进制。
my $bin = printf("%b", $hex);
它打印二进制值。有没有办法将十六进制转换为bin而不打印它?
谢谢,SLP
十进制,二进制和十六进制是数字的所有文本表示(即写入数字的方式)。计算机不能将这些作为数字来处理。
my $num = 0xFA1F;
将指定的数字(六万四千三十一)存入$num
。它以硬件理解的格式存储,但这不是很重要。重要的是它存储为数字,而不是文本。
当print
被要求打印一个数字时,它会以十进制打印出来(或者如果大/小就用科学记数法打印出来)。它不知道如何创建(从一个十六进制常量?来自添加?等),所以它无法确定如何根据它输出数字。
要将数字打印为十六进制,您可以使用
my $hex = 'FA1F'; # $hex contains the hex representation of the number.
print $hex; # Prints the hex representation of the number.
要么
my $num = 0xFA1F; # $num contains the number.
printf "%X", $num; # Prints the hex representation of the number.
您正在使用十六进制格式分配整数值。 print
默认以十进制格式打印数字,因此您获得的是64031。
您可以使用printf()通过提供不同的格式来验证这一点。
$ perl -e ' my $num = 0xFA1F; printf("%d %X %b\n", ($num) x 3 ) '
64031 FA1F 1111101000011111
$ perl -e ' my $num = 64031; printf("%d %X %b\n", ($num) x 3 ) '
64031 FA1F 1111101000011111
$ perl -e ' my $num = 0b1111101000011111; printf("%d %X %b\n", ($num) x 3 ) '
64031 FA1F 1111101000011111
$
要在字符串中获取0xFA1F的二进制格式,可以使用sprintf()
$ perl -e ' my $hex = 0xFA1F; my $bin=sprintf("%b",$hex) ; print "$bin\n" '
1111101000011111
$
让我们按顺序解决每一点困惑
my $hex = 0xFA1F;
这在$hex
中存储了一个十六进制常量,但是Perl没有十六进制数据类型,所以尽管你可以编写十六进制常量,以及二进制和八进制常量,Perl将它们全部转换为十进制。请注意,两者之间存在很大差异
my $hex = 0xFA1F;
和
my $hex = '0xFA1F';
第一个将一个数字存储到$ hex中,当你打印出来时你得到一个十进制数字,第二个存储一个字符串,当打印出来时会给出0xFAF1
但是可以传递给hex()
函数转换为十进制。
$hex = hex($hex);
十六进制函数将字符串转换为十六进制数并返回十进制值,并且到目前为止,$hex
只被用作数字Perl首先将字符串化$hex
然后将字符串传递给hex()
函数进行转换该值从十六进制到十进制。
所以对解决方案。你几乎在那里使用printf()
,有一个名为sprintf()
的函数,它采用与printf()
相同的参数,但不是打印格式化的值,而是将其作为字符串返回。所以你需要的是。
my $hex = 0xFA1F;
my $bin = sprintf("%b", $hex);
print $bin;
技术说明:是的我知道Perl在内部将所有数字都存储为二进制数,但是不能去那里寻求答案,好吗?
如果你可以使用发行版,我写了Bit::Manip来使我的原型设计在处理寄存器时更容易一些(如果你在编译XS代码时遇到问题,还有一个Pure Perl版本可用)。
它不仅可以从数字中取出位,还可以切换,清除,设置等:
use warnings;
use strict;
use Bit::Manip qw(:all);
my $register = 0xFA1F;
# fetch the bits from register using msb, lsb
my $msbyte = bit_get($register, 15, 8);
print "value: $msbyte\n";
print "bin: " . bit_bin($msbyte) . "\n";
# or simply:
# printf "bin: %b\n", $msbyte;
输出:
value: 250
bin: 11111010
这是我写的blog post,它展示了如何使用一些软件的功能和示例数据表寄存器。