7

次の2つのコードに出くわしました。他の場合と同様にランタイム例外をスローする浮動小数点の例外をスローしないのはなぜですか。

class FloatingPoint
    {
      public static void main(String [] args)
       {
         float a=1000f;
         float b=a/0;
        System.out.println("b=" +b);
       }
    }

出力:b=無限大

int 値を使用しようとすると、実行時例外がスローされます。なぜこのようになっているのですか?

4

4 に答える 4

13

短い答え

整数型 ( JLS 4.2.1 ) は、浮動小数点型 ( JLS 4.2.3 ) とは明確に異なります。動作や操作には類似点があるかもしれませんが、両者を混同すると多くの落とし穴につながるような特徴的な違いもあります。

ゼロ除算時の動作の違いは、これらの違いの 1 つにすぎません。したがって、短い答えは、言語がそう言っているので、Java はこのように動作するということです。


整数値と浮動小数点値について

整数型の値は、次の範囲の整数です。

  • byte: から-128まで127、包括的、つまり[-27, 27-1]
  • short: から-32768まで32767、包括的、つまり[-215, 215-1]
  • int: から-2147483648まで2147483647、包括的、つまり[-231, 231-1]
  • long: から-9223372036854775808まで9223372036854775807、包括的、つまり[-263, 263-1]
  • char、 から'\u0000'まで、つまり'\uffff'から0まで65535、つまり[0, 216-1]

浮動小数点型はfloatdoubleであり、概念的には単精度 32 ビットおよび倍精度 64 ビット形式のIEEE 754値および演算に関連付けられています。

それらの値は、最小から最大の順に次のように並べられます。

  • 負の無限大、
  • 負の有限の非ゼロ値、
  • 正および負のゼロ (つまり0.0 == -0.0)、
  • ゼロでない正の有限値、および
  • 正の無限大。

さらに、順序付けされていない特殊なNot-a-Number ( NaN) 値があります。これは、どちらか (または両方!) のオペランドが次の場合を意味します。NaN

  • 数値比較演算子<<=>、および>=returnfalse
  • 数値等価演算子==が返すfalse
  • 数値不等式演算子!=が返すtrue

特に、x != xは であるtrue場合にのみxですNaN

たとえばdouble、無限大 およびは次のNaNように参照できます。

float状況はおよびに類似していFloatます。


例外がスローされる可能性がある場合

Exception数値演算は、次の場合にのみ をスローできます。

  1. NullPointerExceptionnull参照のボックス化解除変換が必要な場合
  2. ArithmeticException、整数除算/剰余演算の右辺がゼロの場合
  3. OutOfMemoryError、ボクシング変換が必要で、十分なメモリがない場合

それらは、落とし穴の一般的な原因であるという観点から、重要度の高い順に並べられています。一般的に言えば:

  • 他のすべての参照型と同様に、ボックス型には特に注意してください。null
  • 整数除算/剰余演算の右辺には特に注意してください
  • 算術オーバーフロー/アンダーフローによって例外がスローされることはありません
  • 精度が失われても例外がスローされることはありません
  • 数学的に不定な浮動小数点演算によって例外がスローされることはありません

ゼロ除算について

整数演算の場合:

  • ArithmeticException右辺がゼロの場合、除算と剰余演算がスローされます

浮動小数点演算の場合:

  • 左オペランドがNaNまたは0の場合、結果は になりNaNます。
  • 演算が除算の場合、オーバーフローし、結果は符号付き無限大になります
  • 演算が剰余の場合、結果はNaN

すべての浮動小数点演算の一般的なルールは次のとおりです。

  • オーバーフローする操作は、符号付き無限大を生成します。
  • アンダーフローする演算は、非正規化値または符号付きゼロを生成します。
  • 数学的に明確な結果を持たない操作は、 を生成しNaNます。
  • NaNオペランドとしてのすべての数値演算はNaN、結果として生成されます。

付録

このすでに長い回答でカバーされていない問題がまだたくさんありますが、読者は関連する質問や参考資料を参照することをお勧めします。

関連する質問

于 2010-08-01T09:52:20.157 に答える
12

フロートは実際には、計算しようとしている「数値」の表現を持っているためです。だからそれを使う。整数にはそのような表現はありません。

Java は (ほとんどの場合) 浮動小数点のサポートに関して IEEE754 に従います。詳細については、こちらを参照してください。

于 2010-08-01T04:35:39.903 に答える
2

これは、(除算/剰余ゼロ) の場合を除いて、整数演算は常にその結果をラップするためです。
float の場合、オーバーフローまたはアンダーフローが発生すると、ラップは 0、無限大、または NaN になります。
オーバーフロー中は無限大になり、アンダーフロー中は 0 になります
。ここでも、正と負のオーバーフロー/アンダーフローがあります。
試す:

float a = -1000;
float b = a/0;
System.out.println("b=" +b);

これにより、負のオーバーフロー

出力が得られます

b=-無限大

同様に、正のアンダーフローは 0 になり、負のアンダーフローは -0 になります。
特定の演算では、float/double によって NaN (Not a Number) が返される場合もあります。
例:

float a = -1000;
double b = Math.sqrt(a);
System.out.println("b=" +b);

出力

b=NaN

于 2010-08-01T08:09:04.693 に答える
1

これは、/ をゼロ値で表すためのプログラミングおよび数学の標準です。float は、JAVA でそのような値を表すことをサポートしています。int (整数) データ型は、JAVA で同じように表現する方法がありません。

小切手 :

http://en.wikipedia.org/wiki/Division_by_zero

http://www.math.utah.edu/~pa/math/0by0.html

于 2010-08-01T08:46:14.070 に答える