Skip to content

Commit 5c3d6ff

Browse files
authored
extend schubfach tests (#772)
1 parent 9e2f9bd commit 5c3d6ff

11 files changed

+1891
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package com.fasterxml.jackson.core.io.jdk;
2+
3+
import org.junit.Test;
4+
5+
import static org.junit.Assert.assertEquals;
6+
7+
public abstract class DoubleToStringTest {
8+
abstract String f(double f);
9+
10+
private void assertD2sEquals(String expected, double f) {
11+
assertEquals(expected, f(f));
12+
}
13+
14+
@Test
15+
public void simpleCases() {
16+
assertD2sEquals("0.0", 0);
17+
assertD2sEquals("-0.0", Double.longBitsToDouble(0x8000000000000000L));
18+
assertD2sEquals("1.0", 1.0d);
19+
assertD2sEquals("-1.0", -1.0d);
20+
assertD2sEquals("NaN", Double.NaN);
21+
assertD2sEquals("Infinity", Double.POSITIVE_INFINITY);
22+
assertD2sEquals("-Infinity", Double.NEGATIVE_INFINITY);
23+
}
24+
25+
@Test
26+
public void switchToSubnormal() {
27+
assertD2sEquals("2.2250738585072014E-308", Double.longBitsToDouble(0x0010000000000000L));
28+
}
29+
30+
/**
31+
* Floating point values in the range 1.0E-3 <= x < 1.0E7 have to be printed
32+
* without exponent. This test checks the values at those boundaries.
33+
*/
34+
@Test
35+
public void boundaryConditions() {
36+
// x = 1.0E7
37+
assertD2sEquals("1.0E7", 1.0E7d);
38+
// x < 1.0E7
39+
assertD2sEquals("9999999.999999998", 9999999.999999998d);
40+
// x = 1.0E-3
41+
assertD2sEquals("0.001", 0.001d);
42+
// x < 1.0E-3
43+
assertD2sEquals("9.999999999999998E-4", 0.0009999999999999998d);
44+
}
45+
46+
@Test
47+
public void minAndMax() {
48+
assertD2sEquals("1.7976931348623157E308", Double.longBitsToDouble(0x7fefffffffffffffL));
49+
assertD2sEquals("4.9E-324", Double.longBitsToDouble(1));
50+
}
51+
52+
@Test
53+
public void roundingModeEven() {
54+
//result differs to Schubfach
55+
assertD2sEquals("-2.1098088986959632E16", -2.109808898695963E16);
56+
}
57+
58+
@Test
59+
public void regressionTest() {
60+
assertD2sEquals("4.940656E-318", 4.940656E-318d);
61+
assertD2sEquals("1.18575755E-316", 1.18575755E-316d);
62+
assertD2sEquals("2.989102097996E-312", 2.989102097996E-312d);
63+
assertD2sEquals("9.0608011534336E15", 9.0608011534336E15d);
64+
//next result differs to Schubfach
65+
assertD2sEquals("4.7083560247115121E18", 4.708356024711512E18);
66+
assertD2sEquals("9.409340012568248E18", 9.409340012568248E18);
67+
// This number naively requires 65 bit for the intermediate results if we reduce the lookup
68+
// table by half. This checks that we don't lose any information in that case.
69+
assertD2sEquals("1.8531501765868567E21", 1.8531501765868567E21);
70+
assertD2sEquals("-3.347727380279489E33", -3.347727380279489E33);
71+
// Discovered by Andriy Plokhotnyuk, see #29.
72+
assertD2sEquals("1.9430376160308388E16", 1.9430376160308388E16);
73+
assertD2sEquals("-6.9741824662760956E19", -6.9741824662760956E19);
74+
assertD2sEquals("4.3816050601147837E18", 4.3816050601147837E18);
75+
}
76+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package com.fasterxml.jackson.core.io.jdk;
2+
3+
import org.junit.Test;
4+
5+
import static org.junit.Assert.assertEquals;
6+
7+
public abstract class FloatToStringTest {
8+
abstract String f(float f);
9+
10+
private void assertF2sEquals(String expected, float f) {
11+
assertEquals(expected, f(f));
12+
}
13+
14+
@Test
15+
public void simpleCases() {
16+
assertF2sEquals("0.0", 0);
17+
assertF2sEquals("-0.0", Float.intBitsToFloat(0x80000000));
18+
assertF2sEquals("1.0", 1.0f);
19+
assertF2sEquals("-1.0", -1f);
20+
assertF2sEquals("NaN", Float.NaN);
21+
assertF2sEquals("Infinity", Float.POSITIVE_INFINITY);
22+
assertF2sEquals("-Infinity", Float.NEGATIVE_INFINITY);
23+
}
24+
25+
@Test
26+
public void switchToSubnormal() {
27+
//next one different to Schubfach
28+
assertF2sEquals("1.17549435E-38", Float.intBitsToFloat(0x00800000));
29+
}
30+
31+
/**
32+
* Floating point values in the range 1.0E-3 <= x < 1.0E7 have to be printed
33+
* without exponent. This test checks the values at those boundaries.
34+
*/
35+
@Test
36+
public void boundaryConditions() {
37+
// x = 1.0E7
38+
assertF2sEquals("1.0E7", 1.0E7f);
39+
// x < 1.0E7
40+
assertF2sEquals("9999999.0", 9999999.0f);
41+
// x = 1.0E-3
42+
assertF2sEquals("0.001", 0.001f);
43+
// x < 1.0E-3
44+
assertF2sEquals("9.999999E-4", 0.0009999999f);
45+
}
46+
47+
@Test
48+
public void minAndMax() {
49+
assertF2sEquals("3.4028235E38", Float.intBitsToFloat(0x7f7fffff));
50+
assertF2sEquals("1.4E-45", Float.intBitsToFloat(0x00000001));
51+
}
52+
53+
@Test
54+
public void roundingModeEven() {
55+
//all different to Schubfach
56+
assertF2sEquals("3.3554448E7", 3.3554448E7f);
57+
assertF2sEquals("8.9999995E9", 8.999999E9f);
58+
assertF2sEquals("3.4366718E10", 3.4366717E10f);
59+
}
60+
61+
@Test
62+
public void roundingEvenIfTied() {
63+
assertF2sEquals("0.33007812", 0.33007812f);
64+
}
65+
66+
@Test
67+
public void looksLikePow5() {
68+
// These are all floating point numbers where the mantissa is a power of 5,
69+
// and the exponent is in the range such that q = 10.
70+
assertF2sEquals("6.7108864E17", Float.intBitsToFloat(0x5D1502F9));
71+
//next 2 are slightly different to Schubfach
72+
assertF2sEquals("1.34217728E18", Float.intBitsToFloat(0x5D9502F9));
73+
assertF2sEquals("2.68435456E18", Float.intBitsToFloat(0x5E1502F9));
74+
}
75+
76+
@Test
77+
public void regressionTest() {
78+
assertF2sEquals("4.7223665E21", 4.7223665E21f);
79+
assertF2sEquals("8388608.0", 8388608.0f);
80+
assertF2sEquals("1.6777216E7", 1.6777216E7f);
81+
assertF2sEquals("3.3554436E7", 3.3554436E7f);
82+
assertF2sEquals("6.7131496E7", 6.7131496E7f);
83+
assertF2sEquals("1.9310392E-38", 1.9310392E-38f);
84+
assertF2sEquals("-2.47E-43", -2.47E-43f);
85+
assertF2sEquals("1.993244E-38", 1.993244E-38f);
86+
assertF2sEquals("4103.9004", 4103.9003f);
87+
assertF2sEquals("5.3399997E9", 5.3399997E9f);
88+
assertF2sEquals("6.0898E-39", 6.0898E-39f);
89+
assertF2sEquals("0.0010310042", 0.0010310042f);
90+
//next one is more accurate than Schubfach
91+
assertF2sEquals("2.8823261E17", 2.8823261E17f);
92+
assertF2sEquals("7.038531E-26", 7.038531E-26f);
93+
//next 2 are more accurate than Schubfach
94+
assertF2sEquals("9.2234038E17", 9.2234038E17f);
95+
assertF2sEquals("6.7108872E7", 6.7108872E7f);
96+
//next one matches Schubfach but not Ryu (Ryu is more accurate)
97+
assertF2sEquals("9.8E-45", 1.0E-44f);
98+
//next one is less accurate than Schubfach
99+
assertF2sEquals("2.81602484E14", 2.816025E14f);
100+
assertF2sEquals("9.223372E18", 9.223372E18f);
101+
assertF2sEquals("1.5846086E29", 1.5846085E29f);
102+
assertF2sEquals("1.1811161E19", 1.1811161E19f);
103+
//next one is less accurate than Schubfach
104+
assertF2sEquals("5.3687091E18", 5.368709E18f);
105+
assertF2sEquals("4.6143166E18", 4.6143165E18f);
106+
assertF2sEquals("0.007812537", 0.007812537f);
107+
assertF2sEquals("1.4E-45", 1.4E-45f);
108+
assertF2sEquals("1.18697725E20", 1.18697724E20f);
109+
assertF2sEquals("1.00014165E-36", 1.00014165E-36f);
110+
assertF2sEquals("200.0", 200f);
111+
assertF2sEquals("3.3554432E7", 3.3554432E7f);
112+
}
113+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.fasterxml.jackson.core.io.jdk;
2+
3+
import org.junit.runner.RunWith;
4+
import org.junit.runners.JUnit4;
5+
6+
@RunWith(JUnit4.class)
7+
public class JdkDoubleTest extends DoubleToStringTest {
8+
@Override
9+
String f(double f) {
10+
return Double.toString(f);
11+
}
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.fasterxml.jackson.core.io.jdk;
2+
3+
import org.junit.runner.RunWith;
4+
import org.junit.runners.JUnit4;
5+
6+
@RunWith(JUnit4.class)
7+
public class JdkFloatTest extends FloatToStringTest {
8+
@Override
9+
String f(float f) {
10+
return Float.toString(f);
11+
}
12+
}

0 commit comments

Comments
 (0)