(bool)(i & 1)和i % 2 == 1是相同的吗?(涉及IT技术)

28
当变量i为int类型时,表达式 (bool)(i & 1)i % 2 == 1 是否相同?请注意:“始终”指所有平台(即使一个字节为16位)和C、C++的所有标准都一样。编辑后的说明:在支持 bool 类型的所有 C 和 C++ 标准中都是如此。

在 C 语言中,bool 不是预定义的。你需要 #include <stdbool.h>,它将其定义为 _Bool_Bool 是 C99 语言的一部分)。 - pmg
7
@pmg:对的,但如果有人问关于“printf”的问题,我不会说:“printf在C中没有预定义。你需要#include <stdio.h>”。然而,在“所有C标准”中谈论布尔变量是误导人的,因为它在任何形式上都不在C89中。 - Steve Jessop
1
没错,就是这个意思 --- bool 并非在所有的 C 标准中都被预定义 :) - pmg
1
最好使用 i % 2 != 0 来测试奇数。 - starblue
2个回答

50

不。

int的1s' 补码表示方式中,-1的表示形式为1 ... 10,因此它们是不同的。

无论如何,对于负数ii%2可以是负数(实际上在C99中当它不等于0时必须是负数),因此不等于负奇数的1。


1
+1:这是正确的答案。(您已经确定了它们可以不同的两个原因!) - Oliver Charlesworth
2
@Kiril:位运算符作用于值的二进制表示。如果“-1&1”为1,则C实现不使用1s'补码,而与底层硬件对此的看法无关。它模拟2s'补码或符号-幅度。 - Steve Jessop
3
@Kiril说:在带符号类型中,<<>>有相当受限的定义——使用负的左操作数进行<<操作是未定义行为。使用负的左操作数进行>>操作则是实现定义的结果。因此,它们是不安全的。C99标准6.5.7/4和/5。 - Steve Jessop
@Steve - 啊,是的,我的意思是非负值(对于 >><< )。所以,你的意思是,如果我需要解析一个头部(例如从套接字接收到的数据),并且头部大于1B,我不能只使用 & 检查某个具体位,而且还需要检查补码然后再使用 & 吗?我很震惊。 - Kiril Kirov
1
使用位运算符对有符号类型进行编码基本上是错误的,除非出于极端优化的原因,这些原因完全是特定于实现的,因此您不需要使其可移植。对于位操作,请使用无符号类型,或者至少要求值为非负数,然后您就知道确切的表示形式。话虽如此,除了2的补码之外的任何东西都极为罕见,因此记录您的代码“仅限于2的补码实现可移植”不太可能给您的用户带来不便。 - Steve Jessop
显示剩余11条评论

9

例如,当 i 为 -1 时,请尝试运行以下代码:-1 % 2 == -1(bool) (-1 & 1) 的结果为 1。

(假设采用二进制补码表示法)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接