2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

371. Sum of Two Integers - 演算子を使わずに合計値を算出する

Posted at

1. はじめに

この問題では、演算子 +- を使わずに、2数の合計値を算出する。

問題文は次の通り。

Given two integers a and b, return the sum of the two integers without using the operators + and -.

2. 解法

演算子の使用が制限されているので、ビット演算で解くことを考える。

ビット演算は、ハードウェアの加算器の基本原理と同じ仕組みで、XOR(排他的論理和)とAND(論理積)を用いることで足し算を行うことができる。

2.1. XOR(排他的論理和)

XORは剰余2の加算で、繰り上がりを無視した和を表す。例えば、2 + 3 の場合は、2進数で $2 = (10)_2$、$3 = (11)_2$ なので、繰り上がりを無視して各ビットを XOR すると次のようになる。

(10)_{2} \oplus (11)_{2} = (01)_{2}

2.2. AND(論理積)

ANDは繰り上がりが発生する位置を表す。

各ビットを見たときに、1 + 1 の場合にのみ繰り上がりが生じるため、ビットごとの AND をとることで、どの桁で繰り上がりが起きるのかを求めることができる。

2進数で 2 = (10)_2、3 = (11)_2 のとき、AND の結果は次のようになる。

(10)_{2} \land (11)_{2} = (10)_{2}

ただし、この値自体は繰り上がりが発生した桁を示しているだけなので、実際の加算では1ビット左にシフトして次のけたに繰り上げる必要がある。

((10)_{2} \land (11)_{2}) \ll 1 = (100)_{2}

最後に、それぞれで求めた結果の排他的論理和(XOR)をとることで、求める結果を得ることができる。

(100)_{2} \oplus (01)_{2} = (101)_{2}

結果は $(101)_{2}$ となり、求めたい結果の 5 と一致する。

3. 実装

Rust で実装した結果を次に示す。

impl Solution {
    pub fn get_sum(a: i32, mut b: i32) -> i32 {
        let mut ans = a;

        while b != 0 {
            let carry = (ans & b) << 1;
            ans ^= b;
            b = carry;
        }

        ans
    }
}

繰り上がり(=b)が 0 になるまでループを回し、計算を行っていく。

4. まとめ

演算子を使わずに、ビット演算で加算および減算を定義できることを確認した。同様の考え方は減算や乗算など、他の算術演算の実装にも応用可能である。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?