🔄

浮動小数点の計算は順序によって結果が変わることをGoのプログラムで確認する

2023/07/08に公開

動機

パタヘネ本を読んで勉強していて、浮動小数点は計算の順序によって結果が変わるので信頼できないと心得よ、という話を得た。
また、タイムリーなことに浮動小数点数の加算の順序にハマった話という記事も発見したので、自分で試してみたくなった。

実装

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も用意しておきました。

https://go.dev/play/p/pllW2sWvZBN

Discussion