代码
public int getSum(int a, int b) {
while (b != 0) {
int sign = (a & b) << 1;
a = a ^ b;
b = sign;
}
return a;
}
画图直观理解
🔑用显微镜放大时间轴
低位进位对高位的影响不是一蹴而就,而是一步一步蝴蝶效应形成的。
一个 timestamp只能从低位向相邻的前一高位产生影响。
即下面每张图代表一个时间戳,由2个箭头所指的二进制数形成上方的一个进位(与)和下方的一个非进位(异或)
timestamp 1
timestamp 2
timestamp 3
timestamp 4
这段代码如何计算和(文字)
代码中的 while 循环会一直执行,直到没有更多的进位需要处理。在每次循环中:
- 使用按位与(
&)和左移(<<)计算当前的进位。 - 使用按位异或(
^)计算加上两个数但不包括进位的结果。 - 将进位赋值给
b,将不包括进位的加法结果赋值给a。 - 当
b变为0,意味着没有更多的进位需要加上,a中存储了完整的加法结果。
例如:
假设 a = 5(二进制 0101)和 b = 3(二进制 0011):
- 计算进位:
sign = (0101 & 0011) << 1->0001 << 1->0010 - 加上数但不包括进位:
a = 0101 ^ 0011->0110(即十进制的6) - 为下一次循环更新
b:b = 0010
再次运行循环:
- 计算进位:
sign = (0110 & 0010) << 1->0010 << 1->0100 - 加上数但不包括进位:
a = 0110 ^ 0010->0100(即十进制的4) - 为下一次循环更新
b:b = 0100
最后一次循环:
- 计算进位:
sign = (0100 & 0100) << 1->0100 << 1->1000 - 加上数但不包括进位:
a = 0100 ^ 0100->0000(即十进制的0) - 为下一次循环更新
b:b = 1000
因为 b 不为0,所以我们再次循环:
- 计算进位:
sign = (0000 & 1000) << 1->0000 << 1->0000 - 加上数但不包括进位:
a = 0000 ^ 1000->1000(即十进制的8) - 为下一次循环更新
b:b = 0000
现在 b 为0,循环结束,a 是 1000(即十进制的8),这是5和3相加的正确结果