3

来自“精通 Perl/第 16 章/位运算符/一元非,~”:

一元 NOT 运算符(有时称为补码运算符)~,根据体系结构的整数大小返回值的按位否定或 1 的补码

为什么下面的脚本会输出两个不同的值?

#!/usr/local/bin/perl
use warnings;
use 5.012;
use Config;

my $int_size = $Config{intsize} * 8;

my $value = 0b1111_1111;
my $complement = ~ $value;

say length sprintf "%${int_size}b", $value;
say length sprintf "%${int_size}b", $complement;

输出:

32  
64
4

2 回答 2

3

intsize 给出了 C 'int' 的宽度,但“架构的整数大小”是指 Perl 实际将使用的整数大小,这取决于它的配置方式。使用$Config{'ivsize'}(或 uvsize;两者应该相同)来查看它有多长(或使用 ivtype/uvtype 来查看 C 类型是什么)。

在您看到两个长度之间存在差异的地方,intsize 为 4,但 ivsize 为 8。您使用的格式%32b设置最小输出宽度为 32;$value 仅使用 8 个字符,因此填充为 32,但 $complement 使用 64 个字符。

于 2010-12-31T14:38:52.383 回答
2

关键短语是“基于架构的整数大小”。您在 64 位架构上运行它,因此补码将作为 64 位整数返回。在 32 位架构上运行代码会产生32 32.

使用Devel::Peek::Dump,您可以看到它$complement是一个无符号整数,而$value不是。这篇文档表明无符号整数至少为 32 位,但取决于平台。我只能假设它们的意思是“取决于本地 C 编译器调用的' long '”而不是 int,因为大多数编译器(包括 GCC)在 64 位架构上使用 32 位整数。

于 2010-12-31T08:17:18.853 回答