XOR と AND の 繰り 上がりで、 + を 使わずに 2 つの 整数を足す
+ と
海外で定番の問題リスト 4 本には入っていません
問題
足し算のa と b の+ と - の+=、++ なども
aとbは -1000000000 以上 1000000000 以下です。和は 32 ビットの 符号つき整数 (-2147483648 以上 2147483647 以下 ) に 収まります - 負の
数は、 32 ビットの 2 の 補数として扱います
入力と出力の例
例 1
例 2
負の
例 3
負の
面接での聞かれ方
面接では、
- 「+ を
使わずに 2 つの 整数を 足してください」 - 正の
数で 書けると、 「負の 数では どうなりますか?」と続きます - Python で
書くと、 「整数に 上の 限りが 無いと、 ループが 止まりますか?」と 聞かれます
1 ビットの
ヒント
まだ開いていません
付箋は 3 枚。下の段ほど答えに近づきます
ヒント 2
ヒント 3答えに近い
アルゴリズムのチートシートの「配列と文字列」に、
関わる学び
配列と
まず 考える手順
段 1
1 ビットどうしの
段 2
全部のa ^ b が(a & b) << 1 がa を a ^ b、b を
段 3
負のint が 64 ビットなので、int32 に0xFFFFFFFF の mask で
解答
Python
Python
def add_without_plus(a, b):
mask = 0xFFFFFFFF
a &= mask
b &= mask
while b != 0:
carry = ((a & b) << 1) & mask
a ^= b
b = carry
if a > 0x7FFFFFFF:
return ~(a ^ mask)
return aJavaScript
JavaScript
function addWithoutPlus(a, b) {
while (b !== 0) {
const carry = (a & b) << 1;
a ^= b;
b = carry;
}
return a;
}Go
Go
func addWithoutPlus(a, b int) int {
x, y := int32(a), int32(b)
for y != 0 {
carry := (x & y) << 1
x ^= y
y = carry
}
return int(x)
}Python の~(a ^ mask) は、a をa ^ mask で 32 ビットの~ でa - (1 << 32) と- を
計算量
- 時間は O(1) です。
繰り 上がりは 毎回 1 ビット以上上へ 動くので、 32 回ほどで 終わります - 使う
記憶は O(1) です - 幅を w ビットと
すれば、 時間は O(w) です
よく ある間違い
- Python で mask を
付けない。 例 2 の -8 と 5 なら 止まりますが、 -1 と 1 のように 繰り 上がりが 上へ 進み続ける 組では、 Python の 整数に 上の 限りが 無いため、 ループが いつまでも 止まりません - Python で
最後に 負の 数へ 直さない。 例 3 で、 32 ビットの -15 を 符号なしで 読んだ 4294967281 を 返してしまいます - Go で
intのまま回す。 64 ビットのまま回しても 答えは 合うことが 多いですが、 32 ビットの 符号つきとして 扱うという 条件から 外れます。 int32に直すと、 問題の 約束どおり 32 ビットでは み出した 分を 捨てられます - 繰り
上がりを 左へずらし忘れる。 a & bは、その位で 繰り 上がりが 出る 所です。 足すのは 1 つ上の 位なので、 << 1を付けます
解答を動かした版 Python 3.14.7Node.js 24.22.1Go 1.24.2確認日 2026年11月8日
面接での 話し方の例
書き始める
「繰り
上がりを 無視した和は XOR、 繰り 上がりは AND を 1 ビット左へずらした値です。 この 2 つを また 足せば よいので、 繰り 上がりが 0 に なるまで 置き換えを 繰り返します。 負の 数の ために 32 ビットで 回します。 JavaScript は そのまま、 Go は int32、Python は mask で 切って 最後に 符号を 直します。 時間も 記憶も O(1) です。」
書き終えたら、
「例 1 の 13 と 29 は、
2 進で 01101 と 11101 です。 XOR は 10000 で 16、 AND を 左へずらすと 11010 で 26 です。 次は 16 と 26 で、 XOR が 01010 の 10、 繰り 上がりが 100000 の 32 です。 10 と 32 は 重なる ビットが 無いので、 XOR の 42 で、 繰り 上がりは 0 に なって 終わりです。」