乗算、除算、モジュロ演算子を使用せずに2つの整数を除算します。



Divide Two Integers Without Using Multiplication



説明

整数型メモリオーバーフローの最大値が返された場合、結果を得るための2つの数値に加えて、乗算、除算、モジュロ(MOD)などを計算することはできません。 2つの入力数値、最初の数値は被除数、除数は2番目の除数、要件は乗算、除算、モジュロ(MOD)などの前提演算ではなく、2つの数値の除算結果を取得することを説明します。

考え

ai = 1を設定する最も簡単な方法の1つは、被除数>除数が満たされている場合、被除数と除数のサイズを比較すると、除数=除数+除数、i ++は、被除数>除数を決定し続け、条件が満たされるまでループを続けます。 iのサイズの場合、出力が満たされません。



この方法は最もシンプルで直感的ですが、これが処理時間のタイムアウトになるまで考えてみてください。

それで、どの方法がそれを掛け算して割り算するのに似ているか、シフトを考えました。例:ここで、数値int i = 2を定義し、実行された場合はi = i<< 1, then i is equal to 4 in this case, equivalent to a multiplication of the two. To get results quickly, we can add a shift operation, how to use? Used where?



ここで、簡単な例として、方法を提案します。2つの入力数、13の被除数、除数が2であるとすると、ここでは段階的な方法を説明します。

1、被除数= 13、除数= 2とします。グローバル変数result = 0を設定し、最終結果を格納します。結果は一時的に提供されますre = 1、1は除数の現在の値の大きさを表し、除数は等しいプリミティブに。

2、被除数が左の除数よりも大きいかどうかを判断するには、その被除数>除数<< is established? Founded then the size of the left one divisor (ie, multiplied by 2) will not exceed the dividend, then step 3. Otherwise, step 4.



3、re = re<<, divisor = divisor <<, return to step 2.

4、現在の被除数から現在の除数を引いたものが元の除数と等しいかどうかを判断するために、被除数> = 2が確立され、設定され、次に2のスペースで除算されますが、除数が変更されました。 、さらに配当の一部もステップ5に渡され、それ以外の場合は、確立されていない場合はステップ6、ステップ6に渡されます。

5、一時的な最初の結果値から結果の最終結果への移動、したがって、被除数=被除数-除数、除数はリセットされます。つまり、除数= 2、ステップ2を再度許可します。

6、値の結果を返します。

各ステップの下には、配当配当、除数除数、中間結果、および最終結果の結果の状態が示されています。

ステップ配当除数の結果

1 13 2 1 0

2 13 2<<=4 1<<=2 0

3 13 4<<=8 2<<=4 0

413-8 2 = 5リセットしてリセット1re +結果= 4 + 0 = 4

5 5 2<<=4 1<<=2 4

65-4 = 2は1にリセットされますre +結果= 2 + 4 = 6

それからあなたは比較することができません、そして結果は6、ビンゴです!

以下のコードを貼り付けます。

public static int divide(int dividend, int divisor) { // special case: when the divisor is zero, it must be out of memory if(divisor==0) return Integer.MAX_VALUE // determine the sign bit int sign = 1 if((dividend>0 && divisor<0) || (dividend0)) sign = -1 // defined as a Long object to a memory overflow while not taking the absolute value // sor1 appear as a local divisor long dend = Math.abs((long)dividend), sor = Math.abs((long)divisor), sor1=sor @ Special cases: when the dividend is zero or less than the dividend the divisor, the return value must be 0 if(dividend==0 || dend sor1<<1){ // qualifying circumstances, the divisor left one, left one intermediate results (intermediate results of size equal to the current sor1 / sor the number of results) re=re<<1 sor1=sor1<<1 } result = result+re // At this time, the divisor has been described intermediate to a critical point, i.e., less than the current the current dividend divisor, but the left one will be greater than the dividend. // dend determine whether the difference between the current divisor is greater than equal to the original divisor, if equal, indicating that there is room in addition to, then after the update cycle divisor and dividend return, otherwise end if((dend-sor1)>= sor){ dend=dend-sor1 sor1=sor }else break } // judge memory overflow if(result*sign>Integer.MAX_VALUE || result*sign
|_+_|