1. ホーム

[解決済み】Javaは整数のアンダーフローやオーバーフローをどのように処理し、どのようにチェックするのでしょうか?

2022-04-01 22:46:46

質問内容

Javaは整数のアンダーフローとオーバーフローをどのように処理するのですか?

続いて、この現象が発生していることをどのように確認/テストするのでしょうか?

解決方法は?

オーバーフローしたら、また 最小値 であり、そこから継続する。もしアンダーフローなら 最大値 で、そこから続けていきます。

以下のように事前に確認することができます。

public static boolean willAdditionOverflow(int left, int right) {
    if (right < 0 && right != Integer.MIN_VALUE) {
        return willSubtractionOverflow(left, -right);
    } else {
        return (~(left ^ right) & (left ^ (left + right))) < 0;
    }
}

public static boolean willSubtractionOverflow(int left, int right) {
    if (right < 0) {
        return willAdditionOverflow(left, -right);
    } else {
        return ((left ^ right) & (left ^ (left - right))) < 0;
    }
}

(に置き換えることができます。 int によって long についても同様のチェックを行う。 long )

もし、このようなことが頻繁に起こるようであれば、より大きな値を格納できるデータ型やオブジェクトを使用することを検討してください。 long または java.math.BigInteger . 最後のものはオーバーフローしません。実質的には、利用可能なJVMのメモリが限界です。


もし、あなたがすでにJava8を使用しているのであれば、新しい Math#addExact() Math#subtractExact() メソッドを投げます。 ArithmeticException をオーバーフローさせることができます。

public static boolean willAdditionOverflow(int left, int right) {
    try {
        Math.addExact(left, right);
        return false;
    } catch (ArithmeticException e) {
        return true;
    }
}

public static boolean willSubtractionOverflow(int left, int right) {
    try {
        Math.subtractExact(left, right);
        return false;
    } catch (ArithmeticException e) {
        return true;
    }
}

ソースコードはこちら こちら こちら をそれぞれ作成します。

もちろん boolean ユーティリティ・メソッドです。