Mod演算子がオーバーフローする理由

Mod演算子は余りを求める演算子です。たとえば、「7 ÷ 3 = 2 余り 1」の場合の1を計算します。

そして、Mod演算子は内部的にLong型の範囲が演算可能範囲になります。そのため、上の例の7にあたる元の値や、3にあたる割る値がLong型の範囲を超えている場合にオーバーフローが発生します。Long型の範囲は-2,147,483,648(-2の31乗) から 2,147,483,647(2の31乗 – 1)です。

-2,147,483,648(-2の31乗)より小さい値や、2,147,483,647(2の31乗 – 1)より大きい値をMod演算子で使うとオーバーフローが発生します。

オーバーフローが発生するコード例

元の値がLong型の範囲を超えている場合

割る値がLong型の範囲を超えている場合

 

Mod演算子のオーバーフローを回避するには

Mod演算子のオーバーフローを回避する方法は2通りあります。

1つはLong型の範囲を超える値を使わないことです。ただ、この方法は実際には採用できないことがありえます。

もう1つはLong型の範囲を超えても大丈夫なようにMod演算子を使わずに余りを求める方法です。

Mod演算子を使わずに余りを求める方法

Mod演算子を使わなくても余りを求めることは可能です。

オーバーフローの原因はLong型の範囲に制限されていることのため、その制限を無くしてしまえばオーバーフローは発生しません。

具体的には以下の計算式で余りを算出します。

余り = 元の値 – Fix(元の値 ÷ 割る値) × 割る値

サンプルコード

上で紹介した計算式を使って、Mod演算子を使わずに余りを求めるサンプルコードです。