C#では、if..else、ループなどのようなものを使用せずに2つの32ビット整数の合計を実行することは可能ですか?
つまり、ビットごとの演算OR(|
)、AND(&
)、XOR(^
)、NOT(!
)、左にシフト(<<
)および右シフト(>>
)?
ここにあなたの娯楽の例があります
unsigned int myAdd(unsigned int a, unsigned int b)
{
unsigned int carry = a & b;
unsigned int result = a ^ b;
while(carry != 0)
{
unsigned int shiftedcarry = carry << 1;
carry = result & shiftedcarry;
result ^= shiftedcarry;
}
return result;
}
ループを展開できます。実行回数は、オペランドに設定されたビット数に依存しますが、unsigned int
の幅より大きくなることはありません。 carry
が0
になったら、次の繰り返しで何も変わりません。
これを試して:
private int add(int a, int b) {
if(b == 0)
return a;
return add( a ^ b, (a & b) << 1);
}
編集:if
ステートメントを修正
少しずつ加算がどのように行われるかを考えてください。値をシフトして各オペランドの各ビットを順番に取得し、2ビットの4つの可能な値を調べて、結果ビットがどうあるべきか、心配するキャリービットがあるかどうかを調べます。次に、ビット単位演算を使用して結果とキャリーを計算する方法を確認します。
public static int getSum(int p, int q)
{
int carry=0, result =0;
for(int i=0; i<32; i++)
{
int n1 = (p & (1<<(i)))>>(i); //find the nth bit of p
int n2 = (q & (1<<(i)))>>(i); //find the nth bit of q
int s = n1 ^ n2 ^ carry; //sum of bits
carry = (carry==0) ? (n1&n2): (n1 | n2); //calculate the carry for next step
result = result | (s<<(i)); //calculate resultant bit
}
return result;
}
Intとして32ビットを取ると、32ビットかかります。ありがとう!!!
static int binaryadd(int x, int y)
{
while (x != 0)
{
int c = y & x;
y = y ^ x;
x = c << 1;
}
return y;
}
int Add(int a, int b)
{
int result = 0,
// carry now contains common set bits of "a" and "b"
carry = a & b;
if (Convert.ToBoolean(carry))
{
// Sum of bits of "a" and "b" where at least one
// of the bits is not set
result = a ^ b;
// carry is shifted by one so that adding it
// to "a" gives the required sum
carry = carry << 1;
result = add(carry, result);
}
else
{
result = a ^ b;
}
return result;
}
XOR ^
演算子とキャリービットは、AND &
演算子。 a
とb
が同じ位置にビットを設定していない場合、^
演算子は、a
とb
の合計を返します。
geeksforgeeks からのコメント