"int mask = ~0;" 的目的是什么?
What is the purpose of "int mask = ~0;"?
我在 C 中看到了下面这行代码 here
int mask = ~0;
我已经在 C 和 C++ 中打印了 mask
的值。它总是打印 -1
.
所以我有一些问题:
- 为什么要将值
~0
赋给 mask 变量?
~0
的目的是什么?
- 我们可以用
-1
代替 ~0
吗?
这是一种可移植的方式,可以将整数中的所有二进制位设置为 1 位,而无需知道当前架构中整数中有多少位。
C 和 C++ 允许 3 种不同的有符号整数格式:符号大小、一个补码和两个补码
~0
将生成全 1 位 ,而不管系统使用的符号格式如何。所以它比-1
更便携
您可以添加 U
后缀(即 -1U
)以生成全 1 位模式 可移植1。然而 ~0
表明意图更清楚 :反转值 0 中的所有位,而 -1 将表明需要负一的值,而不是其二进制表示
1 因为无符号运算总是 reduced modulo the number that is one greater than the largest value that can be represented by the resulting type
在 2 的补码平台上(假设)给你 -1,但规则禁止直接写 -1(仅整数 0..255,一元 !
,~
和二进制 &
、^
、|
、+
、<<
和 >>
是允许的)。
在所有计算机体系结构中都有多种编码数字的方法。当使用 2 的补码时,这将始终为真:~0 == -1
。另一方面,一些计算机使用 1 的补码来编码负数,而上面的例子是不正确的,因为 ~0 == -0
。是的,1s 补码有负零,这就是为什么它不是很直观。
所以对于你的问题
- 将 ~0 分配给掩码,因此掩码中的所有位都等于 1 -> 使
mask & sth == sth
- 无论使用何种平台,~0 用于使所有位都等于 1
- 如果您确定您的计算机平台使用 2 的补码编码,您可以使用 -1 而不是 ~0
我个人的想法 - 让你的代码尽可能独立于平台。成本相对较小,代码成为fail proof
您正在研究一项编码挑战,其中对执行给定任务的运算符和语言结构有许多限制。
第一个问题是 return 值 -1 没有使用 -
运算符。
在用二进制补码表示负数的机器上,值 -1
的所有位都设置为 1
,因此 ~0
的计算结果为 -1
:
/*
* minusOne - return a value of -1
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 2
* Rating: 1
*/
int minusOne(void) {
// ~0 = 111...111 = -1
return ~0;
}
文件中的其他问题并不总是正确执行。第二个问题,returning 一个布尔值表示 int
值适合 16 位带符号 short
的事实有一个缺陷:
/*
* fitsShort - return 1 if x can be represented as a
* 16-bit, two's complement integer.
* Examples: fitsShort(33000) = 0, fitsShort(-32768) = 1
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 8
* Rating: 1
*/
int fitsShort(int x) {
/*
* after left shift 16 and right shift 16, the left 16 of x is 00000..00 or 111...1111
* so after shift, if x remains the same, then it means that x can be represent as 16-bit
*/
return !(((x << 16) >> 16) ^ x);
}
左移负值或移位值超出int
范围的数字有未定义的行为,右移负值是实现定义的,所以上面的解决方案是不正确的(虽然它可能是预期的解决方案)。
很久以前,这就是您在极其有限的设备(例如 1K ZX 80 或 ZX 81 计算机)上节省内存的方式。在 BASIC 中,你会
Let X = NOT PI
而不是
LET X = 0
由于数字存储为 4 字节浮点数,后者比第一个 NOT PI 替代方案多占用 2 个字节,其中 NOT 和 PI 各占用一个字节。
我在 C 中看到了下面这行代码 here
int mask = ~0;
我已经在 C 和 C++ 中打印了 mask
的值。它总是打印 -1
.
所以我有一些问题:
- 为什么要将值
~0
赋给 mask 变量? ~0
的目的是什么?- 我们可以用
-1
代替~0
吗?
这是一种可移植的方式,可以将整数中的所有二进制位设置为 1 位,而无需知道当前架构中整数中有多少位。
C 和 C++ 允许 3 种不同的有符号整数格式:符号大小、一个补码和两个补码
~0
将生成全 1 位 ,而不管系统使用的符号格式如何。所以它比-1
您可以添加 U
后缀(即 -1U
)以生成全 1 位模式 可移植1。然而 ~0
表明意图更清楚 :反转值 0 中的所有位,而 -1 将表明需要负一的值,而不是其二进制表示
1 因为无符号运算总是 reduced modulo the number that is one greater than the largest value that can be represented by the resulting type
在 2 的补码平台上(假设)给你 -1,但规则禁止直接写 -1(仅整数 0..255,一元 !
,~
和二进制 &
、^
、|
、+
、<<
和 >>
是允许的)。
在所有计算机体系结构中都有多种编码数字的方法。当使用 2 的补码时,这将始终为真:~0 == -1
。另一方面,一些计算机使用 1 的补码来编码负数,而上面的例子是不正确的,因为 ~0 == -0
。是的,1s 补码有负零,这就是为什么它不是很直观。
所以对于你的问题
- 将 ~0 分配给掩码,因此掩码中的所有位都等于 1 -> 使
mask & sth == sth
- 无论使用何种平台,~0 用于使所有位都等于 1
- 如果您确定您的计算机平台使用 2 的补码编码,您可以使用 -1 而不是 ~0
我个人的想法 - 让你的代码尽可能独立于平台。成本相对较小,代码成为fail proof
您正在研究一项编码挑战,其中对执行给定任务的运算符和语言结构有许多限制。
第一个问题是 return 值 -1 没有使用 -
运算符。
在用二进制补码表示负数的机器上,值 -1
的所有位都设置为 1
,因此 ~0
的计算结果为 -1
:
/*
* minusOne - return a value of -1
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 2
* Rating: 1
*/
int minusOne(void) {
// ~0 = 111...111 = -1
return ~0;
}
文件中的其他问题并不总是正确执行。第二个问题,returning 一个布尔值表示 int
值适合 16 位带符号 short
的事实有一个缺陷:
/*
* fitsShort - return 1 if x can be represented as a
* 16-bit, two's complement integer.
* Examples: fitsShort(33000) = 0, fitsShort(-32768) = 1
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 8
* Rating: 1
*/
int fitsShort(int x) {
/*
* after left shift 16 and right shift 16, the left 16 of x is 00000..00 or 111...1111
* so after shift, if x remains the same, then it means that x can be represent as 16-bit
*/
return !(((x << 16) >> 16) ^ x);
}
左移负值或移位值超出int
范围的数字有未定义的行为,右移负值是实现定义的,所以上面的解决方案是不正确的(虽然它可能是预期的解决方案)。
很久以前,这就是您在极其有限的设备(例如 1K ZX 80 或 ZX 81 计算机)上节省内存的方式。在 BASIC 中,你会
Let X = NOT PI
而不是
LET X = 0
由于数字存储为 4 字节浮点数,后者比第一个 NOT PI 替代方案多占用 2 个字节,其中 NOT 和 PI 各占用一个字节。