JVMで0fと-0fの違い

結局「ScalaのMapが0fと-0fを同時にkeyに持てない」のが意図的な仕様なのかは、よくわかってない。 あと、逆に「Javaでは0fと-0fを同時にKeyとして持つことができるようにする」ために、わざわざ0fと-0fのjava.lang.Floatに関して、hashCodeとequalsに例外設けてるってこと?
4
zakki @k_matsuzaki

List.groupBy でデータが減るような…なんでぇ

2013-07-03 20:20:21
zakki @k_matsuzaki

浮動小数点数比較の素敵な挙動のお陰な気がする

2013-07-03 20:29:24
zakki @k_matsuzaki

scala> (0f) == (-0f) res0: Boolean = true scala> (-0f).hashCode res1: Int = -2147483648 scala> (0f).hashCode res2: Int = 0 うぇーい

2013-07-03 22:42:44
zakki @k_matsuzaki

ScalaがどうこうというよりJVM一般で浮動小数点数のhashCodeとequalsの実装は注意深くやんないと危ないな

2013-07-03 22:54:30
zakki @k_matsuzaki

あー、java.lang.Float.valueOf(x) でhashCode呼ぶ時はimplicitに変換されるけど==比較ではプリミティブ型のままだからか

2013-07-03 23:04:41
zakki @k_matsuzaki

java.lang.Floatの挙動は -0f!=0f で一貫してるしscala-library.jarの問題とも言いがたいけど合わせると気に食わないこの挙動はなに…

2013-07-03 23:06:52
Kenji Yoshida @xuwei_k

@k_matsuzaki わかりずらいですけど、java.lang.Floatが0fと-0fでequalにならない(つまりhashCode違ってもいい)のは、Java自体の仕様らしいので http://t.co/CBjbmTmLgC それで合ってるんですかね、たぶん・・・

2013-07-04 02:18:26
Kenji Yoshida @xuwei_k

http://t.co/CBjbmTmLgC 「この定義によって、ハッシュテーブルは正しく動作します。」のアルゴリズムの詳しい解説ってどこかないの?

2013-07-04 02:36:38
zakki @k_matsuzaki

@xuwei_k そうですね。java.lang.Floatには問題ありませんし、scalaのタプルもプラスマイナス区別せず比較とハッシュすると一貫してます。唯のFloatでボクシング起きるときが気持ち悪い…

2013-07-04 10:43:35
Kenji Yoshida @xuwei_k

う、でも Scala と Java で 0f と -0f を Map のkeyにした場合の挙動違う・・・ https://t.co/djdszstihL

2013-07-04 10:48:02
ウィザード級エクセラー @BlackPrincessW

@xuwei_k scalaはhashCode取らないんですね。Javaの場合、キーが実質的にjava.lang.Float.valueOf(0f).hashCode()となっているので、0fと-0fだとhashCodeが違うので別と認識されますよ。

2013-07-04 10:51:39
Kenji Yoshida @xuwei_k

.@BlackPrincessW hashCode取らないんじゃなくて、正確には java.lang.Float.valueOf(-0f).## は0だけど、java.lang.Float.valueOf(-0f).hashCode は-2147483648とかそのあたりの事情が

2013-07-04 10:54:35
Yasushi Abe @yasushia

hashFromDouble もだめだろうなぁ。なんでこうなってるんだろう。

2013-07-04 11:03:23
Yasushi Abe @yasushia

そもそもfloatとかdoubleで==すんな、ってのはわかるけど

2013-07-04 11:06:02
Kenji Yoshida @xuwei_k

Set(Double.NaN, Double.NaN).size res0: Int = 2 new java.util.HashSet[Double]{add(Double.NaN);add(Double.NaN)}.size res1: Int = 1

2013-07-04 17:32:40