2017-02-10 12 views
5

は限り浮動小数点が使用されているように、0.1はメモリ内で正確に表現することはできませんので、我々は、この値は通常0.10000000000000004に出てくることを知っています。Google Goで0.1 + 0.2が0.3になるのはなぜですか?

しかしとき0.1と0.2を追加するために行くを使用しました。 私は0.3を得ています。

fmt.Println(0.1 + 0.2) 
// Output : 0.3 

0.30000000000000004の代わりに0.3が表示されるのはなぜですか?

+0

Goは、コンパイル時に余分な精度を使用しているため、移動式を定数倍しませんことを確認してください。 – user2357112

+0

新しいことに感謝します! – Integral

答えて

5

あなたが(例えばfmtパッケージで)それを印刷する場合、印刷機能が既に小数の桁数の一定量に丸めるためです。

const ca, cb = 0.1, 0.2 
fmt.Println(ca + cb) 
fmt.Printf("%.20f\n", ca+cb) 

var a, b float64 = 0.1, 0.2 
fmt.Println(a + b) 
fmt.Printf("%.20f\n", a+b) 

出力(Go Playground上でそれを試してみてください):それはタイプfloat64の(非定数)の値を使用するよりも違うので、我々はconstantsを使用

0.3 
0.29999999999999998890 
0.30000000000000004 
0.30000000000000004441 

まず

は、この例を参照してください。 数値定数は、任意の精度の正確な値を表し、オーバーフローしません。

しかしca+cbの結果を印刷する際に、一定の値がfmt.Println()に渡すことができるように非定数、入力された値に変換する必要があります。この値は、正確に0.3を表すことができないタイプfloat64、となります。しかし、fmt.Println()は~16小数点以下桁数のように丸めます。これは0.3になります。しかし、20桁で表示したいと明示すると、それは正確ではないことがわかります。定数演算0.1+0.2は(コンパイル時に)コンパイラによって評価されるため、0.3のみがfloat64に変換されることに注意してください。

次に、タイプの変数から始めました。驚くことではなく、出力は0.3ではありませんが、デフォルトの丸めでも今回は0.3とは異なる結果が得られました。これは、最初のケース(定数)では変換された0.3でしたが、今回は0.10.2の両方がfloat64に変換されていますが、それらを加算すると0.3fmtパッケージの既定の丸めを使用して「視覚的外観」を作成するのに十分な大きさです。

Why do these two float64s have different values?

How does Go perform arithmetic on constants?

Golang converting float64 to int error

Does go compiler's evaluation differ for constant expression and other expression

:+答え

チェックアウト似た/関連する質問は、トピックについての詳細を知っています

Golang Round to Nearest 0.05

Go: Converting float64 to int with multiplier

+0

ありがとう!すいません遅れました。それはたくさんの助けになりました! – Integral

関連する問題