我试图了解位运算符如何在 C
中工作,但我对 <<
运算符有误解。
我有以下代码:
#include <stdio.h>
int Add(int x, int y);
int Add(int x, int y)
{
while ( y != 0 ) /// Iterate till there is no carry
{
int carry = x & y; /// carry now contains common set bits of x and y
x = x ^ y; /// Sum of bits of x and y where at least one of the bits is not set
y = carry << 1; /// Carry is shifted by one so that adding it to x gives the required sum
}
return x;
}
int main( void )
{
printf( "%d", Add( 13, 17 ) );
return 0;
}
如果我理解正确是这样的:
First Iteration:
|=======================================|
| |
| while ( y != 0 ) |
| while ( 17 != 0 ) |
| while ( 10001 != 00000 ) |
| |
| c = x & y; |
| 1 = 13 & 17 |
| 00001 = 01101 & 10001 |
| |
| x = x ^ y |
| 28 = 13 ^ 17 |
| 11100 = 01101 ^ 10001 |
| |
| y = c << 1 |
| 17 = 1 << 1 |
| 10001 = 00001 << 00001 |
| 00010 = 00001 << 00001 |
| |
|=======================================|
Second Iteration:
|=======================================|
| |
| while ( y != 0 ) |
| while ( 2 != 0 ) |
| while ( 00010 != 00000 ) |
| |
| c = x & y; |
| 0 = 28 & 2 |
| 00000 = 11100 & 00010 |
| |
| x = x ^ y |
| 30 = 28 ^ 2 |
| 11110 = 11100 ^ 00010 |
| |
| y = c << 1 |
| 2 = 0 << 1 |
| 00010 = 00000 << 00001 |
| 00000 = 00000 << 00001 |
| |
|=======================================|
然后
Y
变成 0
并且 X
返回 30
。现在在下面的代码中我有一个问题:
#include <stdio.h>
int main( void )
{
int x = 13;
int y = x << 1; /// 11010 = 01101 << 00001
x = 0 << 1; /// 00000 = 00000 << 00001
printf("y = %d\n", y ); /// 26 | 11010
printf("x = %d\n", x ); /// 26 | 11010
return 0;
}
在这里,如果我理解正确,我们将所有位向左移动一位:
int y = x << 1; /// 11010 = 01101 << 00001
但这里究竟发生了什么:
x = 0 << 1; /// 00000 = 00000 << 00001
x
是否被清除并填充了 0 << 1
的结果? 最佳答案
x
只是分配了表达式 0 << 1
的值。零左移或右移任意量仍然是 0
。
这是正确的,除了替换变量的旧值(在 lhs 上)有点令人困惑,如下例所示。
17 = 1 << 1
10001 = 00001 << 00001
和
2 = 0 << 1
00010 = 00000 << 00001
而是将其描述为:
y = 1 << 1
y = 00001 << 00001
和
y = 0 << 1
y = 00000 << 00001
关于c - 二元加法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54073837/