2ビットを加算すると、次のようになります。(真理値表)
a | b | sum (a^b) | carry bit (a&b) (goes to next)
--+---+-----------+--------------------------------
0 | 0 | 0 | 0
0 | 1 | 1 | 0
1 | 0 | 1 | 0
1 | 1 | 0 | 1
したがって、ビット単位のxorを実行すると、キャリーなしで合計を取得できます。そして、ビット単位で実行し、キャリービットを取得できる場合。
この観測をマルチビット数に拡張しa
、b
a+b = sum_without_carry(a, b) + carry_bits(a, b) shifted by 1 bit left
= a^b + ((a&b) << 1)
一度b
は0
:
a+0 = a
したがって、アルゴリズムは次のように要約されます。
Add(a, b)
if b == 0
return a;
else
carry_bits = a & b;
sum_bits = a ^ b;
return Add(sum_bits, carry_bits << 1);
再帰を取り除き、それをループに変換する場合
Add(a, b)
while(b != 0) {
carry_bits = a & b;
sum_bits = a ^ b;
a = sum_bits;
b = carrry_bits << 1;
}
return a;
上記のアルゴリズムを念頭に置いて、コードからの説明はより簡単になるはずです。
int t = (x & y) << 1;
キャリービット。両方のオペランドの右側の1ビットが1の場合、キャリービットは1です。
y ^= x;
キャリーなしの加算(キャリービットは無視されます)
x = t;
xを再利用して持ち運び用に設定
while(x)
キャリービットが多い間に繰り返します
再帰的な実装(理解しやすい)は次のようになります。
int add(int x, int y) {
return (y == 0) ? x : add(x ^ y, (x&y) << 1);
}
この関数は、+が実際にバックグラウンドでどのように機能するかを示しているようです
いいえ。通常(ほとんどの場合)整数の加算は、マシン命令の加算に変換されます。これは、ビット単位のxorとandを使用した代替実装を示しています。
add
マシン命令を使用すると思います。これは、すべてのCPUが備えており、数クロックで動作するハードウェア加算器として実装されていると思います。