Fixes issue 3569. LongLib.shr gave incorrect results
when the shift amount was greater than 32. This revision adds
two new test cases and modifies LongLib.shr to handle them.
Review by: fabbott
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@5270 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/super/com/google/gwt/lang/LongLib.java b/dev/core/super/com/google/gwt/lang/LongLib.java
index db43c0f..9226113 100644
--- a/dev/core/super/com/google/gwt/lang/LongLib.java
+++ b/dev/core/super/com/google/gwt/lang/LongLib.java
@@ -394,8 +394,17 @@
public static double[] shr(double[] a, int n) {
n &= 63;
double shiftFact = pwrAsDouble(n);
- double newHigh = a[HIGH] / shiftFact;
+ double newHigh = Math.floor(a[HIGH] / shiftFact);
double newLow = Math.floor(a[LOW] / shiftFact);
+
+ /*
+ * Doing the above floors separately on each component is safe. If n<32,
+ * a[HIGH]/shiftFact is guaranteed to be an integer already. For n>32,
+ * a[HIGH]/shiftFact will have fractional bits, but we need to discard them
+ * as they shift away. We will end up discarding all of a[LOW] in this case,
+ * as it divides out to entirely fractional.
+ */
+
return create(newLow, newHigh);
}
diff --git a/dev/core/test/com/google/gwt/lang/LongLibTestBase.java b/dev/core/test/com/google/gwt/lang/LongLibTestBase.java
index 2766669..bd0f38d 100644
--- a/dev/core/test/com/google/gwt/lang/LongLibTestBase.java
+++ b/dev/core/test/com/google/gwt/lang/LongLibTestBase.java
@@ -272,10 +272,13 @@
longFromBits(0x92341234, 0x45674567), 10));
assertEquals(longFromBits(0xffe48d04, 0x8d1159d1), LongLib.shr(
longFromBits(0x92341234, 0x45674567), 10));
+ assertEquals(LongLib.fromInt(67108863), LongLib.shr(longFromBits(0xFFFFFFF,
+ 0xFFFFFFFF), 34));
assertEquals(longFromBits(0x248d04, 0x8d1159d1), LongLib.shru(longFromBits(
0x92341234, 0x45674567), 10));
assertEquals(LongLib.fromInt(-1), LongLib.shr(LongLib.fromInt(-1), 10));
+ assertEquals(LongLib.fromInt(-1), LongLib.shr(LongLib.fromInt(-1), 63));
assertEquals(LongLib.fromInt(-1 << 5), LongLib.shl(LongLib.fromInt(-1), 5));
assertEquals(LongLib.fromInt(-1), LongLib.shl(LongLib.fromInt(-1), 0));