浮動小数点数の比較と定数畳み込み

浮動小数点数を比較する際は気をつけようね!
11
RAO(らお) @RIORAO

[JavaScriptの問題] var a = 0.3 - 0.2; var b = 0.2 - 0.1; var c = a==b; cの中身はどれ?

2017-10-25 02:05:50
RAO(らお) @RIORAO

たくさんの投票ありがとうございました! 今回はJavaScriptの基本的な問題でした。今後も定期的にこういうものを出してみたいと思います(^◇^)

2017-10-27 02:12:55
RAO(らお) @RIORAO

答えは「false」です。 JavaScriptは浮動小数点で実数を表現するため、0.5や0.125などの実数は正確に表すことができますが、0.1や0.2などの実数を正確に表すことができません。 よって、値を丸める際に極小の誤差を生じ、aとbは等しくないと判断されてしまいます。

2017-10-27 02:20:11
RAO(らお) @RIORAO

正確な実数計算をやらされるJavaScriptくん #擬竜戯画 pic.twitter.com/ipE56C2YbV

2017-10-27 02:16:02
拡大
KST @KASServerTF2

@RIORAO 16言語で確認しましたが、trueを返すのはGo言語とD言語だけでした。 #Golang #Dlang #CPP #CSharp #javascript #Ruby #PHP #swift #java #python #rust #kuin #なでしこ #haskell pic.twitter.com/QPrl8unl0E

2017-10-27 03:52:42
拡大
KST @KASServerTF2

プログラミングで a = 0.3 - 0.2 b = 0.2 - 0.1 c = a == b print(c) の結果一覧 #Golang #Dlang #javascript #Ruby #swift #java #python #rust #kuin #なでしこ pic.twitter.com/RqXolhs9hJ

2017-10-27 03:58:16
拡大
KST @KASServerTF2

goもdも浮動小数点のはずなんだが、なんでtrueが返ってくるんだ?

2017-10-27 04:00:49
KST @KASServerTF2

もしかしてconstやfinalつけると結果かわったりする?

2017-10-27 04:01:48
kashi @mkashi

この話は、IEEE754に従う言語なら逆にtrueになっちゃう方に何かおかしなことが起きてる。 twitter.com/KASServerTF2/s…

2017-10-27 21:15:20

Goの場合

morikuni @inukirom

@KASServerTF2 @mattn_jp @RIORAO おそらくGoはコンパイラがa=0.1とb=0.1に変換していると思われます。 添付した画像のコードだとtrueになりますが、constをvarに変更するとfalseになります。constはコンパイル時に計算されますが、varは実行時に計算されるためです。 pic.twitter.com/LpKZF2kOjH

2017-10-27 10:23:00
拡大
ナカニウム @nakaniumu

@inukirom @KASServerTF2 @mattn_jp @RIORAO コンパイル時と実行時で結果が違うのは嫌ですね。クロスコンパイルでプロセッサが違うならいざしらず

2017-10-28 01:26:06
mod_poppo @mod_poppo

こういうやつは同じ2進小数でも精度何ビットかによって結果が変わる(例えば倍精度だと 0.1+0.1+0.1≠0.3 だが単精度だと 0.1+0.1+0.1=0.3 となる)ので、Go言語/D言語の定数畳み込みが何ビットで行われているかが問題

2017-10-27 15:00:00
mod_poppo @mod_poppo

Go言語に関してはこの辺に書いてあるみたいで、浮動小数点数の定数は精度256ビット以上で実装するということになっている(?) golang.org/ref/spec#Const…

2017-10-27 15:06:59
morikuni @inukirom

varで宣言した時点で型が確定するから(おそらくfloat64)コンパイル時に計算されてもfalseになるとのこと。 Go言語の浮動小数点数のお話 - Shogo's Blog shogo82148.github.io/blog/2017/10/2… @shogo82148さんから

2017-10-29 00:10:31

D言語の場合

HOSOKAWA Jun @pik

D言語が True になるのもコンパイラがコンパイル時に最適化しているからではなかろうか? twitter.com/KASServerTF2/s…

2017-10-27 11:24:16
聖哀 @TK_hiziri

2進数、浮動小数点数でやってる限りfalseな気がする むしろD何やってるんだ twitter.com/kasservertf2/s…

2017-10-27 23:43:34
Hajime Hoshi @hajimehoshi

Go はわかるんだけど (untyped constant)、 D はなんでなんでしょう? CC @repeatedly twitter.com/KASServerTF2/s…

2017-10-27 10:51:24
SKS rep @repeatedly

@hajimehoshi うーん,正確なところは吐かれるコードを見てみないと分からんですが,compile time foldingでなるべく精度が保たれたまま計算されている or 中間計算の80bitからdouble(64bit)への変換で同じ値に丸められている,くらいかな?

2017-10-27 11:29:18
SKS rep @repeatedly

浮動小数点の計算の比較で盛り上がっていたのか.まぁD言語で真面目にやるなら,std.mathの関数群をちゃんと使いましょう #dlang

2017-10-27 11:41:48
SKS rep @repeatedly

ほー,golangの場合型がついてないconstだとコンパイラが頑張って精度制限無しで計算しようとするのか.

2017-10-27 11:44:35
SKS rep @repeatedly

D言語もなるべくそうやるようにしてたはずだけど,精度をどこまで頑張るかはよう分からんな.普通にreal精度で持ち回してんのかな?Donとかが詳しそう

2017-10-27 11:46:43
Hajime Hoshi @hajimehoshi

@repeatedly なるほど、そういえば D は 80bit 浮動小数点つかえるんだった

2017-10-27 11:37:27