Skip to content

Commit 531f679

Browse files
committed
Fix float.__hash__()
1 parent b53ae9f commit 531f679

File tree

2 files changed

+36
-47
lines changed

2 files changed

+36
-47
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/floats/FloatBuiltins.java

Lines changed: 3 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -655,49 +655,9 @@ protected static boolean accepts(Object obj) {
655655
@GenerateNodeFactory
656656
@TypeSystemReference(PythonArithmeticTypes.class)
657657
abstract static class HashNode extends PythonUnaryBuiltinNode {
658-
protected boolean noDecimals(float num) {
659-
return num % 1 == 0;
660-
}
661-
662-
protected boolean noDecimals(double num) {
663-
return num % 1 == 0;
664-
}
665-
666-
protected boolean noDecimals(PFloat num) {
667-
return num.getValue() % 1 == 0;
668-
}
669-
670-
@Specialization(guards = {"noDecimals(self)"})
671-
long hashFloatNoDecimals(float self) {
672-
return (long) self;
673-
}
674-
675-
@Specialization(guards = {"!noDecimals(self)"})
676-
@TruffleBoundary
677-
long hashFloatWithDecimals(float self) {
678-
return Float.valueOf(self).hashCode();
679-
}
680-
681-
@Specialization(guards = {"noDecimals(self)"})
682-
long hashDoubleNoDecimals(double self) {
683-
return (long) self;
684-
}
685-
686-
@Specialization(guards = {"!noDecimals(self)"})
687-
@TruffleBoundary
688-
long hashDoubleWithDecimals(double self) {
689-
return Double.valueOf(self).hashCode();
690-
}
691-
692-
@Specialization(guards = {"noDecimals(self)"})
693-
long hashPFloatNoDecimals(PFloat self) {
694-
return (long) self.getValue();
695-
}
696-
697-
@Specialization(guards = {"!noDecimals(self)"})
698-
@TruffleBoundary
699-
long hashPFloatWithDecimals(PFloat self) {
700-
return Double.valueOf(self.getValue()).hashCode();
658+
@Specialization
659+
long hashDouble(double self) {
660+
return PythonObjectLibrary.hash(self);
701661
}
702662
}
703663

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/DefaultPythonDoubleExports.java

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@
4343
import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError;
4444

4545
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
46+
import com.oracle.graal.python.builtins.modules.MathModuleBuiltins;
47+
import com.oracle.graal.python.builtins.modules.SysModuleBuiltins;
4648
import com.oracle.graal.python.builtins.objects.PythonAbstractObject;
4749
import com.oracle.graal.python.builtins.objects.floats.PFloat;
4850
import com.oracle.graal.python.builtins.objects.function.PArguments;
@@ -81,13 +83,40 @@ static long hash(Double number) {
8183
return hash(number.doubleValue());
8284
}
8385

86+
// Adapted from CPython _Py_HashDouble
8487
@Ignore
8588
static long hash(double number) {
86-
if (number % 1 == 0) {
87-
return (long) number;
88-
} else {
89-
return Double.doubleToLongBits(number);
89+
if (!Double.isFinite(number)) {
90+
if (Double.isInfinite(number)) {
91+
return number > 0 ? SysModuleBuiltins.HASH_INF : -SysModuleBuiltins.HASH_INF;
92+
}
93+
return SysModuleBuiltins.HASH_NAN;
94+
}
95+
96+
double[] frexpRes = MathModuleBuiltins.FrexpNode.frexp(number);
97+
double m = frexpRes[0];
98+
int e = (int) frexpRes[1];
99+
int sign = 1;
100+
if (m < 0) {
101+
sign = -1;
102+
m = -m;
103+
}
104+
long x = 0;
105+
while (m != 0.0) {
106+
x = ((x << 28) & SysModuleBuiltins.HASH_MODULUS) | x >> (SysModuleBuiltins.HASH_BITS - 28);
107+
m *= 268435456.0; /* 2**28 */
108+
e -= 28;
109+
long y = (long) m; /* pull out integer part */
110+
m -= y;
111+
x += y;
112+
if (x >= SysModuleBuiltins.HASH_MODULUS) {
113+
x -= SysModuleBuiltins.HASH_MODULUS;
114+
}
90115
}
116+
e = e >= 0 ? e % SysModuleBuiltins.HASH_BITS : SysModuleBuiltins.HASH_BITS - 1 - ((-1 - e) % SysModuleBuiltins.HASH_BITS);
117+
x = ((x << e) & SysModuleBuiltins.HASH_MODULUS) | x >> (SysModuleBuiltins.HASH_BITS - e);
118+
x = x * sign;
119+
return x == -1 ? -2 : x;
91120
}
92121

93122
@ExportMessage

0 commit comments

Comments
 (0)