c - 当按位与应用于负数时会发生什么?
问题描述
我编写并编译了以下代码:
void main()
{
printf("%d", -10 & 5);
}
解决方案
在 C 中,在 binary 的结果中&
,每个位都取决于操作数中对应的两个位。如果相同位置的位在两个操作数中都设置为 (1),则在结果中设置。如果任一操作数中为清除 (0),则结果中为清除。例如,给定位 0011 和 0101,&
运算符将产生 0001,因为只有在最后一个位置是两个操作数中设置的位。
您可能已经知道正整数用二进制表示。位位置从“右侧”的 0 开始编号,然后为 1 表示下一个位置,2、3 等等。位置i的位代表 2 i的值,因此位 0 代表 1,位 1 代表 2,位 2 代表 4,位 3 代表 8,位 4 代表 16,依此类推。所有位表示的值是设置为 1 的位的值的总和。所以 101 表示 5,因为设置了 2 2 = 4 和 2 0 = 1 的位,并且 4+1 = 5。
C 标准指定了 C 实现可用于表示负数的三个规则(在 C 2018 6.2.6.2 2 中):
- 其中一位代表一个符号。如果符号位为 0,则该值与上述相同。如果符号位为 1,则取反。因此,如果第一位是符号位,则 5 是 0101 是 5,-5 是 1101。这称为符号和幅度。
- 其中一位代表一个符号,如果一个数字是负数,则所有位都被反转。所以 5 是 0101,-5 是 1010。这称为反码。
- 其中一位代表一个符号,如果该数字为负数(我们称其为x),则将这些位设置为用于 2 N -<em>x 的模式,其中N是位数。例如,对于四位,2 N = 16,5 是 0101,而 −5 用 16−5 = 11 的位表示,即 1011。这称为二进制补码。
在早期的计算机硬件和软件中,以上所有方法都进行了尝试。最后一个,二进制补码,在现代整数计算中占绝对优势。(大多数浮点使用符号和幅度。)尽管如此,C 标准仍然允许实现使用任何方法。
Because of this, the result of -10 & 5
is implementation-dependent. I will illustrate using eight bits, with a space to group them into two sets of four bits for visibility:
With two’s complement:
- −10 is represented with 1111 0110 (256 − 10 = 246 = 128+64+32+16+4+2), 5 uses 0000 0101, and
−10 & 5
is 0000 0100, which represents 4.
With one’s complement:
- −10 is represented with 1111 0101, 5 uses 0000 0101, and
−10 & 5
is 0000 0101, which represents 5.
With sign and magnitude:
- −10 is represented with 1000 1010, 5 uses 0000 0101, and
-10 & 5
is 0000 0000, which represents 0.
Thus, a C implementation that conforms to the C standard could produce 0, 4, or 5 for -10 & 5
, but 4 is by far the most common result.
推荐阅读
- neo4j - 将 Neo4j 桌面版数据库复制到云端
- fiware - 顺便说一句,Fiware GEris 和 GEi 的区别?
- swift - Cocoa 应用程序不会将数据发送到本地 UDP 套接字
- regex - python - 在python中使用re.findall时如何在两个子表达式的组合上应用`?`?
- python - USB Camera OpenCV 的 YUYV 帧速率比 MJPG 快
- reactjs - React Native 错误:react-native@0.41.2 需要 react@~15.4.0 的对等方
- react-native - react-native-google-places-autocomplete 中的当前位置
- macos - 谷歌浏览器——Command-click 以在 Finder 中显示文件?
- java - 使用 VideoView 观看 mp4-video 显示黑屏
- dask - 杀死由作业产生的任务