任意桁の計算

BigInteger

Java言語の IntegerDouble型は表せる桁数が決まっています.Integerは 32ビット,Longでも64ビットであるため,それぞれ,$-2^{31}〜2^{31} - 1$,$-2^{63}〜2^{63} - 1$ までの値までしか扱えません.

Javaでは任意桁の計算が行える型が存在します.任意桁の整数を表すBigInteger と任意桁の実数を表すBigDecimalです. これらを扱ってみましょう.

BigInteger の初期化

任意桁の整数を表す型です.BigIntegerを利用するときは,import java.math.BigInteger; というimport 文が必要です.BigInteger型の実体を作成するときは,new BigInteger("表したい数") のように数値を文字列で指定してください. この型を扱うとき,通常の四則演算が使えない点に注意してください.

BigInteger value1 = new BigInteger("10");
BigInteger value2 = new BigInteger("20");
BigInteger value3 = value1.add(value2);
// BigInteger value4 = value1 + value2;
    // => コンパイルエラー.

BigInteger の四則演算

上記のように,足し算は addというメソッド呼び出しで実現します. 以下に対応を掲載します.どれも BigInteger型の変数b1b2を使って計算しているものとします.

  • 足し算(b1 + b2
    • b1.add(b2)
  • 引き算(b1 - b2
    • b1.subtract(b2)
  • 掛け算(b1 * b2
    • b1.multiply(b2)
  • 割り算(b1 / b2
    • b1.divide(b2)
  • 割った余り(b1 % b2
    • b1.remainder(b2)
  • 符号反転(-b1
    • b1.negate()
  • 比較
    • b1.compareTo(b2)
      • b1の方が小さければ,負の整数.
        • b1 < b2 ならば b1.compareTo(b2) < 0
      • b1の方が大きければ,正整数.
        • b1 > b2ならば b1.compareTo(b2) > 0
      • 同じ値であれば,0
        • b1 == b2ならば b1.compareTo(b2) == 0

なお,BigDecimalも基本的にはBigIntegerと同じです. メソッド呼び出しで演算を行い,実体を作成するときは,実数を表す文字列を渡せば良いです.

例題 階乗改

第2回目の練習問題 3. 階乗 を改良し, 桁あふれを起こさないようにしましょう. 前回作成した階乗のプログラムは,13!を正確に計算できません.これを BigInteger を使って, どんな数値が与えられたとしても計算できるようにしてください. クラス名をBigFactorialとしてください. コマンドライン引数から値を受け取れるようにしましょう. また,コマンドライン引数で受け取る値はInteger型として扱って良いです.

出力例

$ java Factorial 12 # => 前回のプログラム.正しい結果の限界.
12! = 479001600
$ java Factorial 13 # => 前回のプログラム.正しくない結果.
13! = 1932053504
$ java BigFactorial 11
11! = 39916800
$ java BigFactorial 12 13 14 15
12! = 479001600
13! = 6227020800
14! = 87178291200
15! = 1307674368000