44

次のコードとコメントを考慮してください。

Console.WriteLine(1 / 0); // will not compile, error: Division by constant zero

int i = 0;
Console.WriteLine(1 / i); // compiles, runs, throws: DivideByZeroException

double d = 0;
Console.WriteLine(1 / d); // compiles, runs, results in: Infinity   

コンパイラがゼロ定数による除算と実行時の DivideByZeroException を積極的にチェックしていることは理解できますが、

ゼロ除算で double を使用すると、例外がスローされるのではなく、無限大が返されるのはなぜですか? これは仕様によるものですか、それともバグですか?

念のため、これを VB.NET でも実行すると、「より一貫した」結果が得られました。

dim d as double = 0.0
Console.WriteLine(1 / d) ' compiles, runs, results in: Infinity

dim i as Integer = 0
Console.WriteLine(1 / i) '  compiles, runs, results in: Infinity

Console.WriteLine(1 / 0) ' compiles, runs, results in: Infinity

編集:

kekekela のフィードバックに基づいて、次のように実行した結果、無限になりました。

Console.WriteLine(1 / .0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001);

このテストはアイデアを裏付けているようであり、文字通りの2倍0.0は実際には非常に小さな部分であり、無限になります...

4

5 に答える 5

37

一言で言えば、double型は無限の値を定義しますが、型は定義しintません。したがって、このdouble場合、計算の結果は、定義されているため、指定された型で実際に表現できる値です。このint場合、無限には値がないため、正確な結果を返す方法はありません。したがって、例外です。

VB.NET は少し異なる方法で処理を行います。/整数除算は、演算子を使用して自動的に浮動小数点値になります。これは、開発者がたとえば式 を記述し、1 / 2それを評価して に評価できるようにするため0.5です。C# と一貫性のある動作を見たい場合は、これを試してください。

Console.WriteLine(1 \ 0)

上記の整数除算演算子 ( \, not )の使用に注意してください/。例外が発生すると思います (またはコンパイル エラー - どちらかわかりません)。

同様に、これを試してください:

Dim x As Object = 1 / 0
Console.WriteLine(x.GetType())

上記のコードは出力しますSystem.Double

不正確さについては、別の見方があります。doubleタイプが正確にゼロの値を持たないということではありません(そうです)。むしろ、double型はそもそも数学的に正確な結果を提供することを意図していません。(特定の値は正確に表すことができます、はい。しかし、計算は正確さを約束するものではありません。)結局のところ、数式1 / 0の値は定義されていません (最後に確認しました)。しかし1 / x、x がゼロに近づくと無限大に近づきます。したがって、この観点から、とにかくほとんどの分数をn / m 正確に表すことができない場合、ケースを近似として扱い、それに近づくx / 0値を与えることは理にかなっています--繰り返しになりますが、少なくとも無限大が定義されています。

于 2011-01-05T22:34:55.040 に答える
8

doubleは浮動小数点数であり、正確な値ではないため、コンパイラーの観点から実際に除算しているのは、ゼロに近いものですが、正確にはゼロではありません。

于 2011-01-05T22:11:04.400 に答える
2

「数値」浮動小数点はそのようなものではないためです。浮動小数点演算:

  • 関連付けられていません
  • 分配的ではない
  • 乗法逆元を持たない可能性があります

(いくつかの例については、 http://www.cs.uiuc.edu/class/fa07/cs498mjg/notes/floating-point.pdfを参照してください)

浮動小数点は、特定の問題を解決するための構造であり、使用されるべきではない場合に至る所で使用されます。彼らはかなりひどいと思いますが、それは主観的なものです。

于 2013-03-18T21:59:28.190 に答える
2

これは仕様によるものです。これは、型が浮動小数点演算の標準であるIEEE 754doubleに準拠しているためです。Double.NegativeInfinityおよびDouble.PositiveInfinityのドキュメントを確認してください。

この定数の値は、正数または負数をゼロで除算した結果です。

于 2011-01-05T22:28:04.533 に答える
1

これは、IEEE 標準の浮動小数点数と倍精度浮動小数点数が指定された「無限」値を持つという事実と関係がある可能性があります。.NET は、ハードウェア レベルで既に存在するものを公開しているだけです。

これが論理的に理にかなっている理由については、ケケケラの回答を参照してください。

于 2011-01-05T22:27:30.540 に答える