質問では、算術演算子は使用できないとのことなので、論理演算子とシフト演算子から始めるしかありません。
^ (XOR) 演算は 2 つの数値のキャリーなしの合計であることがわかっています。2 つの数値を加算してもキャリーが生成されない場合、合計は 2 つの数値の合計になります。これが問題を解決する鍵です。一般に、2 つの数値を加算すると桁上げが発生しますが、正しい和を求めるには、「桁上げなしの合計」に基づいて桁上げを加算し、最初に桁上げを取得する必要があります。 2 つの数値の対応する位置が両方とも 1 の場合、キャリーが発生することがわかっています。つまり、対応する位置 A&B==1 の条件下では、各ビットのキャリーを取得できますが、キャリーは足し算になります。この 1 を対応する上位の桁に移すので、得られたキャリーを 1 桁左にシフトし、前に取得した「キャリーなしの合計」に加算して、2 つの数値の合計を求めます。
ここで、無限のマトリョーシカ人形を作成できることがわかりました。「キャリーなしの合計」と「生成されたキャリー」の合計を取得するには、これら 2 つの数値をそれぞれ 2 つの新しい数値として扱います。前の演算は、2 つの数値がキャリーを生成できなくなるまで繰り返され、結果は ^ 演算を通じて直接取得できます。
23 16 の値を見つけたとします
##上記の考え方に従って、コードを簡単に書くことができますpublic static int addAB(int A, int B) { // 当两数的产生的进位为 0,就退出循环,返回其无进位和,就是结果 while ((A & B) != 0) { int A_B = A ^ B;// 无进位求和 int AB = (A & B) << 1;// 得到进位 // 接下来就是求 得到的进位 + 无进位之和,重复前面的操作,直到不产生进位 A = A_B; B = AB; } // 最后返回新的无进位之和 return (A ^ B); }
public static void main(String[] args) { int count = 1_0000_0000;// 比较次数 100000000次 Random random = new Random();// 生成随机数字 boolean flag = true;// 相等则为 true for (int i = 0; i < count; i++) { int num1 = random.nextInt(Integer.MAX_VALUE/2);// 随机正数1 int num1_2 = random.nextInt(Integer.MAX_VALUE/2);// 随机正数2 // 随机正数1 + 随机正数2 if ((num1+num1_2) != addAB(num1,num1_2)){ // 有一次不相等的,则退出循环 flag = false; break; } int num2 = -random.nextInt(Integer.MAX_VALUE/2);// 随机负数1 int num2_2 = -random.nextInt(Integer.MAX_VALUE/2);// 随机负数2 // 随机负数1 + 随机负数2 if ((num2+num2_2) != addAB(num2,num2_2)){ // 有一次不相等的,则退出循环 flag = false; break; } int num3 = random.nextInt(Integer.MAX_VALUE);// 随机正数 int num4 = -random.nextInt(Integer.MAX_VALUE);// 随机负数 // 随机正数 + 随机负数 if ((num3+num4) != addAB(num3,num4)){ // 有一次不相等的,则退出循环 flag = false; break; } } System.out.println(flag); }
以上が算術演算子を使用せずに Java で合計を実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。