Skip to content

Commit 1500485

Browse files
committed
fix NumberUtils min/max varargs dropping the sign of zero
1 parent c3e09d3 commit 1500485

2 files changed

Lines changed: 22 additions & 24 deletions

File tree

src/main/java/org/apache/commons/lang3/math/NumberUtils.java

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -761,12 +761,7 @@ public static double max(final double... array) {
761761
// Finds and returns max
762762
double max = array[0];
763763
for (int j = 1; j < array.length; j++) {
764-
if (Double.isNaN(array[j])) {
765-
return Double.NaN;
766-
}
767-
if (array[j] > max) {
768-
max = array[j];
769-
}
764+
max = Math.max(max, array[j]);
770765
}
771766
return max;
772767
}
@@ -804,12 +799,7 @@ public static float max(final float... array) {
804799
// Finds and returns max
805800
float max = array[0];
806801
for (int j = 1; j < array.length; j++) {
807-
if (Float.isNaN(array[j])) {
808-
return Float.NaN;
809-
}
810-
if (array[j] > max) {
811-
max = array[j];
812-
}
802+
max = Math.max(max, array[j]);
813803
}
814804
return max;
815805
}
@@ -1042,12 +1032,7 @@ public static double min(final double... array) {
10421032
// Finds and returns min
10431033
double min = array[0];
10441034
for (int i = 1; i < array.length; i++) {
1045-
if (Double.isNaN(array[i])) {
1046-
return Double.NaN;
1047-
}
1048-
if (array[i] < min) {
1049-
min = array[i];
1050-
}
1035+
min = Math.min(min, array[i]);
10511036
}
10521037
return min;
10531038
}
@@ -1085,12 +1070,7 @@ public static float min(final float... array) {
10851070
// Finds and returns min
10861071
float min = array[0];
10871072
for (int i = 1; i < array.length; i++) {
1088-
if (Float.isNaN(array[i])) {
1089-
return Float.NaN;
1090-
}
1091-
if (array[i] < min) {
1092-
min = array[i];
1093-
}
1073+
min = Math.min(min, array[i]);
10941074
}
10951075
return min;
10961076
}

src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1308,6 +1308,24 @@ void testLang381() {
13081308
assertTrue(Float.isNaN(NumberUtils.max(bF)));
13091309
}
13101310

1311+
@Test
1312+
void testMinMaxSignedZero() {
1313+
// The varargs overloads must agree with Math.min/Math.max (and the three-argument
1314+
// overloads, which delegate to them) on the sign of zero. -0.0 is distinct from 0.0,
1315+
// e.g. 1 / -0.0 is -Infinity, so the raw bits are asserted here.
1316+
assertEquals(Double.doubleToRawLongBits(0.0d), Double.doubleToRawLongBits(NumberUtils.max(-0.0d, 0.0d)));
1317+
assertEquals(Double.doubleToRawLongBits(0.0d), Double.doubleToRawLongBits(NumberUtils.max(0.0d, -0.0d)));
1318+
assertEquals(Double.doubleToRawLongBits(-0.0d), Double.doubleToRawLongBits(NumberUtils.min(-0.0d, 0.0d)));
1319+
assertEquals(Double.doubleToRawLongBits(-0.0d), Double.doubleToRawLongBits(NumberUtils.min(0.0d, -0.0d)));
1320+
assertEquals(Float.floatToRawIntBits(0.0f), Float.floatToRawIntBits(NumberUtils.max(-0.0f, 0.0f)));
1321+
assertEquals(Float.floatToRawIntBits(0.0f), Float.floatToRawIntBits(NumberUtils.max(0.0f, -0.0f)));
1322+
assertEquals(Float.floatToRawIntBits(-0.0f), Float.floatToRawIntBits(NumberUtils.min(-0.0f, 0.0f)));
1323+
assertEquals(Float.floatToRawIntBits(-0.0f), Float.floatToRawIntBits(NumberUtils.min(0.0f, -0.0f)));
1324+
// the varargs result matches the three-argument overload
1325+
assertEquals(Double.doubleToRawLongBits(NumberUtils.max(-0.0d, 0.0d, 0.0d)), Double.doubleToRawLongBits(NumberUtils.max(-0.0d, 0.0d)));
1326+
assertEquals(Double.doubleToRawLongBits(NumberUtils.min(0.0d, -0.0d, 0.0d)), Double.doubleToRawLongBits(NumberUtils.min(0.0d, -0.0d)));
1327+
}
1328+
13111329
@Test
13121330
void testLang747() {
13131331
assertEquals(Integer.valueOf(0x8000), NumberUtils.createNumber("0x8000"));

0 commit comments

Comments
 (0)