13

VS2015 C# インタラクティブで次のスニペットを実行したところ、非常に奇妙な動作が発生しました。

> double divide(double a, double b)
. {
.     try
.     {
.         return a / b;
.     }
.     catch (DivideByZeroException exception)
.     {
.         throw new ArgumentException("Argument b must be non zero.", exception);
.     }
. }    
> divide(3,0)
Infinity    
> 3 / 0
(1,1): error CS0020: Division by constant zero
> var b = 0;
> 3 / b
Attempted to divide by zero.
> 

3 / 0 がエラーをスローし、3 / b がフォーマットされたエラーをスローしたのに、メソッドが無限大を返したのはなぜですか? 無限を返す代わりに、除算でエラーをスローするように強制できますか?

メソッドを次のように再フォーマットすると

double divide(double a, double b)
{
    if ( b == 0 )
    {
        throw new ArgumentException("Argument b must be non zero.", new DivideByZeroException());
    }
    return a / b;
}

新しい DivideByZeroException には、キャッチされた例外と同じ情報と構造がすべて含まれますか?

4

4 に答える 4

22

を使っているからですSystem.Double

MSDN で述べられているようDivideByZeroExceptionに、整数型およびDecimal.

これは、Double 値に対して「いわゆる」ゼロを定義するのが難しいためです。

また、PositiveInfinity は、正の被除数を使用したゼロ除算の結果であり、NegativeInfinity は、負の被除数を使用したゼロ除算の結果です。(ソース: MSDN 再び)

DivideByZeroException は、浮動小数点型には適していません。注:NaNゼロの被除数でゼロ除算を試みると取得できます。

于 2016-07-25T20:04:08.760 に答える
2

3 / 0 がエラーをスローし、3 / b がフォーマットされたエラーをスローしたのに、メソッドが無限大を返したのはなぜですか?

最初のケースでは、0 は整数ではなく、倍精度であるためです。2 番目は整数です。ここで、double は浮動小数点数であることに注意してください。したがって、整数のような正確な値はありません。一方、整数はコンピュータで 100% の精度で表すことができます。

ここでは、浮動小数点数に関する非常に優れた記事を見つけることができます。

于 2016-07-25T20:04:16.527 に答える
1

他の人が上で述べたように、除数として double を使用しているためです。変数の例を使用して証明できますが、double代わりにvar.

> double a = 3;
> double b = 0;
> a/b
∞
于 2016-07-25T20:08:00.913 に答える
-1

Java の Int は 2 の補数です。2 の補数の整数には、Infinity や NaN などの特別な値を格納するために使用できるビットがないため、結果を目的の型で表現できないため、例外をスローする必要があります。浮動小数点数にはこの問題がないため (無限大に使用できるビット パターンがあります)、例外は必要ありません。

于 2016-07-25T20:07:24.313 に答える