Go における浮動小数点精度の違い: リテラルと変数
Go では、浮動小数点演算の動作は、比較すると矛盾しているように見えることがあります。リテラルと変数を含む操作。次のコードを調べてみましょう:
package main import ( "fmt" ) func main() { x := 10.1 fmt.Println("x == 10.1: ", x == 10.1) fmt.Println("x*3.0 == 10.1*3.0:", x*3.0 == 10.1*3.0) fmt.Println("x*3.0: ", x*3.0) fmt.Println("10.1*3.0: ", 10.1*3.0) }
このコードを実行すると、次の出力が表示されます:
x == 10.1: true x*3.0 == 10.1*3.0: false x*3.0: 30.299999999999997 10.1*3.0: 30.3
出力に見られるように、x*3.0 と 10.1*3.0 の比較が示されています。予期せず false と評価されます。このため、なぜこの不一致が発生するのか、またそれが意図的なものなのかバグなのかという疑問が生じます。
設計を理解する
Go では、浮動小数点リテラルと定数の精度は無制限です。 。ただし、型付き変数に代入される場合、その精度はターゲットの型の境界によって制限されます。上の例では、 x := 10.1 はリテラル 10.1 を float64 変数に格納します。この変換では、float64 型の制限により精度がいくらか失われます。
対照的に、式 10.1*3.0 はリテラルに対して直接浮動小数点乗算を実行し、完全な精度を維持します。これは、x の精度の低下が計算に影響を与える x*3.0 と比較してわずかに異なる値になります。
ドキュメントとリソース
Go の公式ドキュメントでは、これが認められています。定数の記事の「Floats」セクションの動作を参照してください。数値定数は任意の精度を持ちますが、代入時に宛先の型に適合する必要があることが説明されています。 1e1000 のような大きな値は、他の定数を含む式で使用できますが、結果がより狭い型で格納される場合、精度が影響を受ける可能性があります。
記事では、この例で観察された特定の動作については明示的に言及していません。 (x*3.0 対 10.1*3.0)、精度の制限が定数と型付き変数にどのように適用されるかについての一般的な理解を提供します。
以上がGo の浮動小数点比較でリテラルと変数の結果が異なるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。