7.3. 大きい数値の取扱
long型で扱える整数の範囲は-2^63以上、2^63-1以下(約9×10^19、約9000京)であり、double型で扱える10進数の範囲は正負とも約1.8×10^308(日本語では表現できません)です。もしそれより大きい範囲の数値を扱いたい場合には、「java.math.BigInteger」「java.math.BigDecimal」を使用します(それより小さい数に対して使用しても構いません)。BigInteger, BigDecimalは任意精度の数を扱えるクラスで、共にMathクラスで提供されているような数値演算に加えて、四則演算・素数判定などのメソッドを提供します。
BigInteger, BigDecimalを使用するためには、数値を表す文字列からインスタンスを作成するのが簡単です。
BigInteger bigInt = new BigInteger("123456789012345678901234567890"); BigDecimal bigDec = new BigDecimal("1.0e500");
四則演算を行うためには、下記に示すメソッドを使用します。BigIntegerの場合を示します。
BigInteger add(BigInteger val) | 指定された数を加算した結果を返します。 |
BigInteger subtract(BigInteger val) | 指定された数を減算した結果を返します。 |
BigInteger multiply(BigInteger val) | 指定された数を乗算した結果を返します。 |
BigInteger divide(BigInteger val) | 指定された数で除算した結果を返します。 |
BigInteger remainder(BigInteger val) | 指定された数で除算した余りを返します。 |
BigDecimalにはremainderメソッドはありません。またdivideメソッドでは引数で結果のスケールや丸め方法を指定します。丸め方法はBigDecimalのクラス変数を用いて指定します。
bigDec = bigDec.divide(new BigDecimal(bigInt), BigDecimal.ROUND_DOWN);
BigIntegerは素数に関するメソッドも提供しています。「isProbablePrime」メソッドは、素数である確率が高い場合に「true」を返すものです。引数で指定した数が高いほど、素数である確率は上がりますが、実行時間も長くなります。「1」を指定した場合には、50%の確率になります。
boolean isPrime = bigInt.isProbablePrime(1);
「probablePrime」メソッドは、クラスメソッドで、素数である確率が高い数を返すものです。引数には確率と、素数を探すソースとなるjava.util.Randomインスタンスを指定します。
BigInteger primeInt = BigInteger.probablePrime(1, new Random());
BigInteger, BigDecimalは、ほかにビット演算に相当するメソッド「and」「xor」など、シフト演算に相当するメソッド「shiftRight」「shiftLeft」(BigDecimalでは「movePointRight」「movePointLeft」)も提供しています。プリミティブ型変数に対してできる演算は、全てメソッドを用いてできると考えて良いでしょう。
(実習課題3)
引数で指定した桁数の整数で、とにかく大きい素数(素数である確率が高い数)を探し出すコンソールプログラムを作成しなさい。