C# 浮動小数点式: 強制型変換と変数代入の違いの分析
C# では、一見単純な浮動小数点算術式が予期しない結果を引き起こす可能性があります。この記事では、この問題を詳しく掘り下げ、観察された違いの根本的な理由を説明します。
問題の説明
次のコード スニペットを考えてみましょう:
<code class="language-csharp">int speed1 = (int)(6.2f * 10); float tmp = 6.2f * 10; int speed2 = (int)tmp;</code>
直感的には、speed1
と speed2
は同じ値を持ち、両方とも 6.2f の 10 倍を表すと予想されます。ただし、実際には、2 つの変数の値は異なります:
<code>speed1 = 61 speed2 = 62</code>
この違いにより、これらの一見同一の操作が異なる結果を生み出すのはなぜでしょうか?という疑問が生じます。
説明
この動作の背後にある理由を理解するには、C# の浮動小数点演算の微妙な点を詳しく調べる必要があります。
最初の式 (int)(6.2f * 10)
では、6.2f * 10
の乗算結果は整数 (32 ビット) に変換される前に倍精度浮動小数点数 (64 ビット) として扱われます。この変換では double の小数部分が切り捨てられるため、結果は 61 になります。
2 番目の式 float tmp = 6.2f * 10
では、乗算の結果が 32 ビット精度の float 変数 (tmp) に格納されます。 tmp
が整数に変換されると、浮動小数点数は最も近い整数に丸められ、結果は 62 になります。
コンパイラの最適化
C# コンパイラーはパフォーマンス上の理由からコードを最適化することに注意してください。 (int)(6.2f * 10)
の場合、コンパイラは中間値を double として保持することを選択する可能性があり、その結果、キャスト中に精度が失われます。ただし、float tmp = 6.2f * 10
の場合、コンパイラは結果を変数に格納する前に最も近い float 値に丸める必要があるため、結果に違いが生じます。
さらに詳しい情報
これをより明確に説明するために、次の演習を考えてみましょう:
<code class="language-csharp">double d = 6.2f * 10; int tmp2 = (int)d; // 计算 tmp2</code>
この例では、乗算結果は整数に変換される前に double 変数に格納され、double データ型は 6.2f * 10 を表現するのに十分な精度を備えているため、tmp2
の値は 62 になります。精度が大幅に低下します。
結論
予期しない結果を回避するには、C# の浮動小数点演算のプロパティを理解することが重要です。キャストと丸めのプロセスの微妙な点を考慮することで、開発者は期待どおりに動作するコードを記述し、潜在的なエラーを回避できます。
以上がC# 浮動小数点式でキャストと変数の代入が異なる結果を生成するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。