( a ^ b ^ c ) + ( ( ( a & b ) | ( b & c ) | ( a & c ) ) << 1 )加法 ...

还没学会如何迈开脚步又怎么能跑起来 ... 三个数字之前 ... 我们先要从两个数字相加开始 ...

首先你要知道计算机里面的数字都是以二进制存储的 ... 你看到的数字 ... 在计算机看来都是 0 和 1 ...

我们随便挑两个数字比如 123 和 321 ... 转化成二进制之后用用竖式把它们加在一起 ...

'    "' 
   001111011  = 123
 + 101000001  = 321
-------------
   110111100  = 444

相同位置对齐 ... 从个位数加起 ... 相加的结果满二进一 ... 这个不用我多说了吧 ..?

' 和 "' 表示由原来的数字产生的进位 ... " 表示由 '

不过事实上 ... 进位这个事情本身也是二进制 ... 0 和 1 嘛 ... 所以不妨就用二进制来表示 ...

'

001111011  ( a
   101000001  ( b
   010000010  ( c

我们得到了三个数字 ... a 和 b 是原来的数字 ... c 是进位 ...

回想我们刚刚竖式计算的过程 ... 是不是每次都是先计算一位的值 ... 然后再看有没有进位要加 ..?

我们现在用程序模拟这个过程 ... 不考虑进位的时候先把 a 和 b 相加 ...

0 ^ 0 = 01 ^ 0 = 10 ^ 1 = 11 ^ 1 = 0+ 而是用 ^^ 就是位运算操作符里面的 按位异或

关于位运算这里就不再赘述了 ...

总之 ... a 和 b 不进位相加之后 ... 我们的式子变成了这样 ...

'
   010000010  ( c
 + 100111010  ( d
-------------
   110111100  = 444

d = a ^ b

但是同时又出现了新的问题 ... 怎么得到 c ..?

回想一下 ... c 是怎么来的 ..? 是由进位转化来的 ... 进位又是怎么来的 ..? 满二进一 ...

也就是当 a 和 b 的某一位同时为 1 的时候 ... c 的相应位置的左边一位为 1 ...

换言之 ... 当 a 和 b 的左起第 n + 1 位同时为 1 的时候则 c 的左起第 n 位为 1 ...

c = ( a & b ) << 1& 是位运算操作符里面的 按位与 ... << 是位运算操作符里面的 左移

如果你认真看了我刚刚说的那个在另外问题里的回答的话 ... 应该不会对这两个操作符有疑问 ...

到现在为止 ... 我们又把 c 和 d 转化回了与 a 和 b 相关的式子 ...

a ^ b ... 进位的部分是 ( a & b ) << 1 所以我们可以得到结论 ... a + b = ( a ^ b ) + ( ( a & b ) << 1 ) ...

绕了一大圈 ... 我们学会了怎么把两个数相加改为另外两个数相加 ...

这个看似没用的式子 ... 恰恰是解决这道题的关键 ...

如果你愿意 ... 可以一直这么写下去 ... 比如把这个式子继续拆分变成下面的样子 ...

(a ^ b) ^ ( ( a & b ) << 1 ) + ( ( a ^ b ) & ( ( a & b ) << 1 ) )

然后继续继续 ... 直到最右边那一项左移若干次之后变成 0 ... 你就实现了完全不用加号的加法 ...

在这个时候 ... 你加上一个新的数字 ... 就实现了一个加号的三个数字相加 ...

当然如果你仍然愿意继续的话 ... 甚至可以实现不用加号的三个数字相加 ...

唯一的问题就是最终的式子会长到一个屏幕都显示不下 ... 各种没法看 ...

所以我们现在回归最初 ... 继续列竖式 ... 看看三个数相加的时候到底发生了什么 ...

我们再随便挑三个数字 ... 比如 111 222 和 333 ...

""#""##''
   0001101111  = 111
   0011011110  = 222
 + 0101001101  = 333
--------------
   1010011010  = 666

' 表示由原来的数字产生的进位 ... " 表示由 '# 表示原来的数字在这里会产生进位但由于 ' 或 "' 和 #

0001101111  ( a
   0011011110  ( b
   0101001101  ( c 0010011110 ( d

我觉得都到现在了 ... 不用我说你应该也可以看出规律了吧 ...

只要 a b c 三个数字的某一位至少有两个为 1 ... 在 d 的相应位置的左边一位就为 1 ...

d = ( ( a & b ) | ( b & c ) | ( a & c ) ) << 1| 是位运算操作符里面的 按位或