[MATH-1145] Fix integer overflows in MannWhitneyUTest. Thanks to Anders Conbere.

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1624756 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Thomas Neidhart 2014-09-13 15:46:38 +00:00
parent 2bc9e7ea86
commit 76f154179b
4 changed files with 23 additions and 3 deletions

View File

@ -176,6 +176,9 @@
<contributor>
<name>Dan Checkoway</name>
</contributor>
<contributor>
<name>Anders Conbere</name>
</contributor>
<contributor>
<name>Charles Cooper</name>
</contributor>

View File

@ -73,6 +73,10 @@ Users are encouraged to upgrade to this version as this release not
2. A few methods in the FastMath class are in fact slower that their
counterpart in either Math or StrictMath (cf. MATH-740 and MATH-901).
">
<action dev="tn" type="fix" issue="MATH-1145" due-to="Anders Conbere">
Fix potential integer overflows in "MannWhitneyUTest" when providing
large sample arrays.
</action>
<action dev="tn" type="fix" issue="MATH-1149" due-to="M Kim">
Fixed potential null pointer dereferencing in constructor of
"DummyStepInterpolator(DummyStepInterpolator)".

View File

@ -145,12 +145,12 @@ public class MannWhitneyUTest {
* U1 = R1 - (n1 * (n1 + 1)) / 2 where R1 is sum of ranks for sample 1,
* e.g. x, n1 is the number of observations in sample 1.
*/
final double U1 = sumRankX - (x.length * (x.length + 1)) / 2;
final double U1 = sumRankX - ((long) x.length * (x.length + 1)) / 2;
/*
* It can be shown that U1 + U2 = n1 * n2
*/
final double U2 = x.length * y.length - U1;
final double U2 = (long) x.length * y.length - U1;
return FastMath.max(U1, U2);
}
@ -230,7 +230,7 @@ public class MannWhitneyUTest {
/*
* It can be shown that U1 + U2 = n1 * n2
*/
final double Umin = x.length * y.length - Umax;
final double Umin = (long) x.length * y.length - Umax;
return calculateAsymptoticPValue(Umin, x.length, y.length);
}

View File

@ -112,4 +112,17 @@ public class MannWhitneyUTestTest {
double result = testStatistic.mannWhitneyUTest(d1, d2);
Assert.assertTrue(result > 0.1);
}
@Test
public void testBigDataSetOverflow() {
// MATH-1145
double[] d1 = new double[110000];
double[] d2 = new double[110000];
for (int i = 0; i < 110000; i++) {
d1[i] = i;
d2[i] = i;
}
double result = testStatistic.mannWhitneyUTest(d1, d2);
Assert.assertTrue(result == 1.0);
}
}