' P '

whatever I will forget

Java BigInteger & BigDecimal

さきほど初めてコンテスト参加してきました! 結果はCまで解けたので目標としてはクリア、嬉しいです。
B問題で4回連続でWAだしてもうダメだ。。となりましたがそこからググりまくってBigIntegerを使って逃げる作戦に変更したらACになってめちゃくちゃ嬉しかったです.
まあこの解き方が正解なのかどうかはおいておいて、値が大きくなる場合としては知っておいたほうがいいと思いました。

atcoder.jp
atcoder.jp

BigInteger

前にも下記の記事で書きましたが、long型で保持できる桁数は19桁までで、それを越えるとオーバーフローが発生します。 mankozooyork.hatenablog.com そのため、それくらいの桁数を扱うのであれば、BigIntegerを使おうって感じです。
意外と宣言やScannerを使った入出力も扱いやすいです。

import

import java.math.BigInteger;

Scannerの場合

Scanner sc = new Scanner(System.in);
BigInteger bi = scanner.nextBigInteger();

配列の宣言

配列も普通に

BigInteger[] array = new BigInteger[array_length];

と書けます。

値の宣言

これはvalueOf()を使うかnewをしましょう

BigInteger bi = BigInteger.valueOf(1000000000000000000L);

値の比較

equals()compareTo()を使いましょう
equals()の場合は比較対象もBigIntegerにしないとだめなので、valueOf()で変換しましょう

計算

まだ掛け算しかやってないのですが、bi.multiply(num)のように行います
これも計算対象はBigIntegerにしないとだめです

サンプル

最初は地道に1000000000000000000を超えたら,, みたいなロジックを書いてたのですが
1000000000000000000 * 1000000000000000000をするとマイナスの値になってもうわけわからなくなりました。

import java.util.Scanner;
import java.math.BigInteger;

public class Main6 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();

        BigInteger[] a = new BigInteger[n];
        for(int i=0; i<n; i++) {
            a[i] = sc.nextBigInteger();
            if(a[i].equals(BigInteger.valueOf(0))) {
                System.out.println(0);
                System.exit(0);
            }
        }
        sc.close();

        BigInteger ans = BigInteger.valueOf(1);
        BigInteger limit = BigInteger.valueOf(1000000000000000000L);
        for(int i=0; i<n; i++) {
            ans = ans.multiply(a[i]);
            if(ans.compareTo(limit) > 0) {
                System.out.println(-1);
                System.exit(0);
            }
        }
        System.out.println(ans);
    }
}

BigDecimal

まあ宣言等はほぼBigIntegerと同じ(BIgInteger部分をBIgDecimalに変えるだけのイメージ)です

サンプル

問題では、整数×少数になったので、整数部分をBigDecimalにしてます
a.multiply()の部分がBigIntegerでaを宣言するとコンパイルエラーになったためです
double型の変数であればBigDecimal.valueOf()が使えました。
最後は切り捨てでよいとなっていたのでそのまんまlong型に出力してる感じです

import java.util.Scanner;
import java.math.BigDecimal;

public class Main7 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        BigDecimal a = sc.nextBigDecimal();
        double b = sc.nextDouble();
        sc.close();

        BigDecimal ans = a.multiply(BigDecimal.valueOf(b));
        System.out.println(ans.longValue());
    }
}

参考

www.geeksforgeeks.org

stackoverflow.com

www.geeksforgeeks.org

www.geeksforgeeks.org

stackoverflow.com