私はこれをやっていた 質問 リートコードで。
リクエスト:
2つの整数aとbの合計を計算しますが、演算子+と-を使用することはできません。
それが与えた解決策を理解できません
誰かがこのgetSum
関数の仕組みを説明できますか?
これがJSの答えです:
var getSum=function(a,b) {
const Sum = a^b; //I can't understand how those two line's code can
const carry = (a & b) << 1; //get the sum
if(!carry) {
return Sum
}
return getSum(Sum,carry);
};
console.log(getSum(5,1));
_^
_はビット単位の演算であるXORです。シングルビットでは、ルールは_0 ^ 0 = 0
_、_0 ^ 1 = 1
_、_1 ^ 0 = 0
_、および_1 ^ 1 = 0
_であり、マルチビット値を処理する場合は、対応するビットで実行するように拡張するだけです。この名前は「exclusive or」の略であり、AまたはBのいずれかが_A ^ B
_である場合に限り、_1
_が_1
_であるという事実に由来します。両方ではありません。ただし、別の名前である⊕について話す方が興味深いです。 ⊕は+ですが、少し異なります。 ⊕の規則は、追加の規則に似ています:_0 + 0 = 0
_、_0 + 1 = 1
_、_1 + 0 = 1
_、および_1 + 1 = 10
_。 ⊕は+ですが、_1 ⊕ 1 = 0
_は除きます。つまり、キャリーなしの場合を除いて、⊕は+です。これは複数のビットに当てはまります:_011 + 001 = 100
_は、1の場所から_1
_を2の場所に運び、次に_1
_を再び4の場所に運びます。次に、_011 ⊕ 001 = 010
_を実行します。
さて、本当の足し算をする時、いつ運ぶの?バイナリでは、答えは非常に簡単です。ある場所に_1
_が2つある場合、_1
_を次の場所に持ち込みます。これは、ビット単位のAND、_&
_として簡単に理解できます。 _1 & 1 = 1
_、それ以外の場合は_0
_。 _011 + 001
_の場合、キャリーなしで加算すると_011 ⊕ 001 = 010
_が得られ、_1
_のため、_011 & 001 = 001
_を1の場所からキャリーする必要があることがわかります。 _(a & b) << 1
_のシフトにより、数値は「どこから実行する必要がありますか」になります。 「キャリーを追加する場所はどこですか?」:_(011 & 001) << 1 = 010
_; 2の場所にキャリービットを追加する必要があります。
したがって、getSum
では、_a + b
_を知りたいと考えています。 _a ^ b
_でキャリーなしで加算を計算し、_(a & b) << 1
_でキャリービットを追加する必要がある場所を見つけます。次に、これら2つを加算するだけです。ええと、数値を一緒に加算する関数は既にあります。 getSum
と呼ばれます。したがって、基本的にはfunction getSum(a, b) { return getSum(a ^ b, (a & b) << 1); }
のみを記述します。ただし、実行するものがない場合は必ず短絡させ、無限再帰を回避します。