Fix floating point number hash code in ranges

Don't make 0.0 and -0.0 have the same hash code: they are different in Java (in
the sense that "Double.valueOf(0.0).equals(Double.valueOf(-0.0))" is false),
and they are considered different already in DoubleRange.equals, which calls
Double.compare, which differentiates them
This commit is contained in:
Alexander Udalov
2014-01-15 16:46:24 +04:00
parent d427fcc187
commit d66c5b2fbe
5 changed files with 11 additions and 17 deletions
@@ -45,9 +45,9 @@ fun areEqualNumbers(kind: ProgressionKind, v: String) = when (kind) {
fun hashLong(v: String) = "($v xor ($v ushr 32))"
fun floatToIntBits(v: String) = "(if ($v != 0.0f) java.lang.Float.floatToIntBits($v) else 0)"
fun floatToIntBits(v: String) = "java.lang.Float.floatToIntBits($v)"
fun doubleToLongBits(v: String) = "if ($v != 0.0) java.lang.Double.doubleToLongBits($v) else 0L"
fun doubleToLongBits(v: String) = "java.lang.Double.doubleToLongBits($v)"
val OUTPUT_DIR: File by Delegates.lazy {
@@ -48,9 +48,7 @@ class GenerateProgressions(val out: PrintWriter) {
BYTE, CHAR, SHORT -> " = 31 * (31 * start.toInt() + end) + increment"
INT -> " = 31 * (31 * start + end) + increment"
LONG -> " = (31 * (31 * ${hashLong("start")} + ${hashLong("end")}) + ${hashLong("increment")}).toInt()"
FLOAT -> " = (31 * (31 * ${floatToIntBits("start")} +\n" +
" ${floatToIntBits("end")}) + \n" +
" ${floatToIntBits("increment")}).toInt()"
FLOAT -> " = 31 * (31 * ${floatToIntBits("start")} + ${floatToIntBits("end")}) + ${floatToIntBits("increment")}"
DOUBLE -> ": Int {\n" +
" var temp = ${doubleToLongBits("start")}\n" +
" var result = ${hashLong("temp")}\n" +
@@ -48,8 +48,7 @@ class GenerateRanges(val out: PrintWriter) {
BYTE, CHAR, SHORT -> " = 31 * start.toInt() + end"
INT -> " = 31 * start + end"
LONG -> " = (31 * ${hashLong("start")} + ${hashLong("end")}).toInt()"
FLOAT -> " = 31 * ${floatToIntBits("start")} +\n" +
" ${floatToIntBits("end")}"
FLOAT -> " = 31 * ${floatToIntBits("start")} + ${floatToIntBits("end")}"
DOUBLE -> ": Int {\n" +
" var temp = ${doubleToLongBits("start")}\n" +
" val result = ${hashLong("temp")}\n" +
+4 -6
View File
@@ -112,9 +112,7 @@ public class FloatProgression(
fun equals(other: Any?): Boolean =
other is FloatProgression && java.lang.Float.compare(start, other.start) == 0 && java.lang.Float.compare(end, other.end) == 0 && java.lang.Float.compare(increment, other.increment) == 0
fun hashCode() = (31 * (31 * (if (start != 0.0f) java.lang.Float.floatToIntBits(start) else 0) +
(if (end != 0.0f) java.lang.Float.floatToIntBits(end) else 0)) +
(if (increment != 0.0f) java.lang.Float.floatToIntBits(increment) else 0)).toInt()
fun hashCode() = 31 * (31 * java.lang.Float.floatToIntBits(start) + java.lang.Float.floatToIntBits(end)) + java.lang.Float.floatToIntBits(increment)
fun toString() = if (increment > 0) "$start..$end step $increment" else "$start downTo $end step ${-increment}"
}
@@ -135,11 +133,11 @@ public class DoubleProgression(
other is DoubleProgression && java.lang.Double.compare(start, other.start) == 0 && java.lang.Double.compare(end, other.end) == 0 && java.lang.Double.compare(increment, other.increment) == 0
fun hashCode(): Int {
var temp = if (start != 0.0) java.lang.Double.doubleToLongBits(start) else 0L
var temp = java.lang.Double.doubleToLongBits(start)
var result = (temp xor (temp ushr 32))
temp = if (end != 0.0) java.lang.Double.doubleToLongBits(end) else 0L
temp = java.lang.Double.doubleToLongBits(end)
result = 31 * result + (temp xor (temp ushr 32))
temp = if (increment != 0.0) java.lang.Double.doubleToLongBits(increment) else 0L
temp = java.lang.Double.doubleToLongBits(increment)
return (31 * result + (temp xor (temp ushr 32))).toInt()
}
+3 -4
View File
@@ -113,8 +113,7 @@ public class FloatRange(public override val start: Float, public override val en
fun equals(other: Any?): Boolean =
other is FloatRange && java.lang.Float.compare(start, other.start) == 0 && java.lang.Float.compare(end, other.end) == 0
fun hashCode() = 31 * (if (start != 0.0f) java.lang.Float.floatToIntBits(start) else 0) +
(if (end != 0.0f) java.lang.Float.floatToIntBits(end) else 0)
fun hashCode() = 31 * java.lang.Float.floatToIntBits(start) + java.lang.Float.floatToIntBits(end)
fun toString() = "$start..$end"
@@ -135,9 +134,9 @@ public class DoubleRange(public override val start: Double, public override val
other is DoubleRange && java.lang.Double.compare(start, other.start) == 0 && java.lang.Double.compare(end, other.end) == 0
fun hashCode(): Int {
var temp = if (start != 0.0) java.lang.Double.doubleToLongBits(start) else 0L
var temp = java.lang.Double.doubleToLongBits(start)
val result = (temp xor (temp ushr 32))
temp = if (end != 0.0) java.lang.Double.doubleToLongBits(end) else 0L
temp = java.lang.Double.doubleToLongBits(end)
return (31 * result + (temp xor (temp ushr 32))).toInt()
}