web-dev-qa-db-ja.com

0.0で除算するときにJavaが例外をスローしないのはなぜですか?

2つの数字の差の割合を計算するコードがあります-(oldNum - newNum) / oldNum * 100;-両方の数字がdoublesです。 oldNumが0の場合、何らかのチェック/例外処理を追加する必要があります。ただし、oldNumとnewNumの両方の値を0.0に設定してテストを実行すると、何も起こらずエラーがスローされなかったように実行が継続されました。このコードをintsで実行すると、確実に算術ゼロ除算例外が発生します。 Javaがdoublesになると無視するのはなぜですか?

68
froadie

ゼロによる除算の結果は、数学的に言えばndefinedであり、float/doubleで表現できます(NaN-数字ではない)、しかし、そうではありません。基本的な意味で間違っています。

整数は特定の数値を保持する必要があるため、それらを処理するときにゼロによる除算でエラーがスローされる必要があります。

45
Kris

Javaのfloatおよびdouble型は、他のほとんどの言語(およびほとんどすべてのハードウェアFPユニット)と同様に、 IEEE 754 標準を実装します浮動小数点演算の場合、ゼロによる除算を要求して特別な「無限大」値を返します。例外をスローすると、実際にはその標準に違反します。

整数演算( 2の補数 Javaおよび他のほとんどの言語とハードウェアによる表現)として実装されており、特別な無限大またはNaN値を持たないため、例外をスローすることは有用な動作です。

110

Doubleの格納方法は、intとはまったく異なります。 Javaが二重計算を処理する方法の詳細な説明については、 http://firstclassthoughts.co.uk/Java/traps/Java_double_traps.html を参照してください。浮動小数点数、特に Not a Number(NaN) の概念。

浮動小数点表現について詳しく知りたい場合は、 このドキュメント (Word形式、申し訳ありません)を読むことをお勧めします。それはあなたの理解に役立つかもしれない数のバイナリ表現を掘り下げます。

5
Mike

Java開発者はdoubleプリミティブ型とDoubleクラスについて知っていますが、浮動小数点演算を行っている間、彼らは_Double.INFINITY_、NaN、_-0.0_およびそれらに関係する算術計算を管理するその他のルール。

この質問に対する簡単な答えは、ArithmeticExceptionをスローせず、_Double.INFINITY_を返さないことです。また、false自体がxであっても、比較_x == Double.NaN_は常にNaNと評価されることに注意してください。

xNaNであるかどうかをテストするには、メソッド呼び出しDouble.isNaN(x)を使用して、指定された数値がNaNかどうかを確認する必要があります。これは、NULLSQLに非常に近いです。

役に立つかもしれません。

4
ziyapathan

ゼロで割った場合(0または0.00)

  1. Doubleを0で除算すると、JVMはInfinityを表示します。

    public static void main(String [] args){ double a=10.00; System.out.println(a/0); }

    コンソール:Infinity

  2. Intを0で除算すると、JVMは算術例外をスローします。

    public static void main(String [] args){ int a=10; System.out.println(a/0); }

    コンソール:_Exception in thread "main" Java.lang.ArithmeticException: / by zero_

  3. しかし、intを0.0で除算すると、JVMはInfinityを表示します。

    public static void main(String [] args){ int a=10; System.out.println(a/0.0); }

    コンソール:Infinity

これは、JVMがcast intをdoubleに自動的に入力するため、ArithmeticExceptionの代わりに無限大を取得するためです。

4
Raman Gupta