🔄
浮動小数点の計算は順序によって結果が変わることをGoのプログラムで確認する
動機
パタヘネ本を読んで勉強していて、浮動小数点は計算の順序によって結果が変わるので信頼できないと心得よ、という話を得た。
また、タイムリーなことに浮動小数点数の加算の順序にハマった話という記事も発見したので、自分で試してみたくなった。
実装
main.go
package main
import (
"fmt"
"math/rand"
)
func main() {
fls := make(map[int]float32)
for i := 0; i < 100000; i++ {
fls[i] = rand.Float32()
}
sum := func(fls map[int]float32) float32 {
var sum float32
for _, f := range fls {
// goのmapのループは順番がランダム
sum += f
}
return sum
}
// 同じfloat32のmapに対してsumを取ってるので、同じになるはず・・・?
fmt.Println(sum(fls))
fmt.Println(sum(fls))
fmt.Println(sum(fls))
fmt.Println(sum(fls))
fmt.Println(sum(fls))
// Output:
// 49923.273
// 49922.965
// 49923.14
// 49923.47
// 49922.89
// ならないですね〜😇
}
The Go Playgroundも用意しておきました。
Discussion