Skip to content

extend schubfach tests #772

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package com.fasterxml.jackson.core.io.jdk;

import org.junit.Test;

import static org.junit.Assert.assertEquals;

public abstract class DoubleToStringTest {
abstract String f(double f);

private void assertD2sEquals(String expected, double f) {
assertEquals(expected, f(f));
}

@Test
public void simpleCases() {
assertD2sEquals("0.0", 0);
assertD2sEquals("-0.0", Double.longBitsToDouble(0x8000000000000000L));
assertD2sEquals("1.0", 1.0d);
assertD2sEquals("-1.0", -1.0d);
assertD2sEquals("NaN", Double.NaN);
assertD2sEquals("Infinity", Double.POSITIVE_INFINITY);
assertD2sEquals("-Infinity", Double.NEGATIVE_INFINITY);
}

@Test
public void switchToSubnormal() {
assertD2sEquals("2.2250738585072014E-308", Double.longBitsToDouble(0x0010000000000000L));
}

/**
* Floating point values in the range 1.0E-3 <= x < 1.0E7 have to be printed
* without exponent. This test checks the values at those boundaries.
*/
@Test
public void boundaryConditions() {
// x = 1.0E7
assertD2sEquals("1.0E7", 1.0E7d);
// x < 1.0E7
assertD2sEquals("9999999.999999998", 9999999.999999998d);
// x = 1.0E-3
assertD2sEquals("0.001", 0.001d);
// x < 1.0E-3
assertD2sEquals("9.999999999999998E-4", 0.0009999999999999998d);
}

@Test
public void minAndMax() {
assertD2sEquals("1.7976931348623157E308", Double.longBitsToDouble(0x7fefffffffffffffL));
assertD2sEquals("4.9E-324", Double.longBitsToDouble(1));
}

@Test
public void roundingModeEven() {
//result differs to Schubfach
assertD2sEquals("-2.1098088986959632E16", -2.109808898695963E16);
}

@Test
public void regressionTest() {
assertD2sEquals("4.940656E-318", 4.940656E-318d);
assertD2sEquals("1.18575755E-316", 1.18575755E-316d);
assertD2sEquals("2.989102097996E-312", 2.989102097996E-312d);
assertD2sEquals("9.0608011534336E15", 9.0608011534336E15d);
//next result differs to Schubfach
assertD2sEquals("4.7083560247115121E18", 4.708356024711512E18);
assertD2sEquals("9.409340012568248E18", 9.409340012568248E18);
// This number naively requires 65 bit for the intermediate results if we reduce the lookup
// table by half. This checks that we don't lose any information in that case.
assertD2sEquals("1.8531501765868567E21", 1.8531501765868567E21);
assertD2sEquals("-3.347727380279489E33", -3.347727380279489E33);
// Discovered by Andriy Plokhotnyuk, see #29.
assertD2sEquals("1.9430376160308388E16", 1.9430376160308388E16);
assertD2sEquals("-6.9741824662760956E19", -6.9741824662760956E19);
assertD2sEquals("4.3816050601147837E18", 4.3816050601147837E18);
}
}
113 changes: 113 additions & 0 deletions src/test/java/com/fasterxml/jackson/core/io/jdk/FloatToStringTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package com.fasterxml.jackson.core.io.jdk;

import org.junit.Test;

import static org.junit.Assert.assertEquals;

public abstract class FloatToStringTest {
abstract String f(float f);

private void assertF2sEquals(String expected, float f) {
assertEquals(expected, f(f));
}

@Test
public void simpleCases() {
assertF2sEquals("0.0", 0);
assertF2sEquals("-0.0", Float.intBitsToFloat(0x80000000));
assertF2sEquals("1.0", 1.0f);
assertF2sEquals("-1.0", -1f);
assertF2sEquals("NaN", Float.NaN);
assertF2sEquals("Infinity", Float.POSITIVE_INFINITY);
assertF2sEquals("-Infinity", Float.NEGATIVE_INFINITY);
}

@Test
public void switchToSubnormal() {
//next one different to Schubfach
assertF2sEquals("1.17549435E-38", Float.intBitsToFloat(0x00800000));
}

/**
* Floating point values in the range 1.0E-3 <= x < 1.0E7 have to be printed
* without exponent. This test checks the values at those boundaries.
*/
@Test
public void boundaryConditions() {
// x = 1.0E7
assertF2sEquals("1.0E7", 1.0E7f);
// x < 1.0E7
assertF2sEquals("9999999.0", 9999999.0f);
// x = 1.0E-3
assertF2sEquals("0.001", 0.001f);
// x < 1.0E-3
assertF2sEquals("9.999999E-4", 0.0009999999f);
}

@Test
public void minAndMax() {
assertF2sEquals("3.4028235E38", Float.intBitsToFloat(0x7f7fffff));
assertF2sEquals("1.4E-45", Float.intBitsToFloat(0x00000001));
}

@Test
public void roundingModeEven() {
//all different to Schubfach
assertF2sEquals("3.3554448E7", 3.3554448E7f);
assertF2sEquals("8.9999995E9", 8.999999E9f);
assertF2sEquals("3.4366718E10", 3.4366717E10f);
}

@Test
public void roundingEvenIfTied() {
assertF2sEquals("0.33007812", 0.33007812f);
}

@Test
public void looksLikePow5() {
// These are all floating point numbers where the mantissa is a power of 5,
// and the exponent is in the range such that q = 10.
assertF2sEquals("6.7108864E17", Float.intBitsToFloat(0x5D1502F9));
//next 2 are slightly different to Schubfach
assertF2sEquals("1.34217728E18", Float.intBitsToFloat(0x5D9502F9));
assertF2sEquals("2.68435456E18", Float.intBitsToFloat(0x5E1502F9));
}

@Test
public void regressionTest() {
assertF2sEquals("4.7223665E21", 4.7223665E21f);
assertF2sEquals("8388608.0", 8388608.0f);
assertF2sEquals("1.6777216E7", 1.6777216E7f);
assertF2sEquals("3.3554436E7", 3.3554436E7f);
assertF2sEquals("6.7131496E7", 6.7131496E7f);
assertF2sEquals("1.9310392E-38", 1.9310392E-38f);
assertF2sEquals("-2.47E-43", -2.47E-43f);
assertF2sEquals("1.993244E-38", 1.993244E-38f);
assertF2sEquals("4103.9004", 4103.9003f);
assertF2sEquals("5.3399997E9", 5.3399997E9f);
assertF2sEquals("6.0898E-39", 6.0898E-39f);
assertF2sEquals("0.0010310042", 0.0010310042f);
//next one is more accurate than Schubfach
assertF2sEquals("2.8823261E17", 2.8823261E17f);
assertF2sEquals("7.038531E-26", 7.038531E-26f);
//next 2 are more accurate than Schubfach
assertF2sEquals("9.2234038E17", 9.2234038E17f);
assertF2sEquals("6.7108872E7", 6.7108872E7f);
//next one matches Schubfach but not Ryu (Ryu is more accurate)
assertF2sEquals("9.8E-45", 1.0E-44f);
//next one is less accurate than Schubfach
assertF2sEquals("2.81602484E14", 2.816025E14f);
assertF2sEquals("9.223372E18", 9.223372E18f);
assertF2sEquals("1.5846086E29", 1.5846085E29f);
assertF2sEquals("1.1811161E19", 1.1811161E19f);
//next one is less accurate than Schubfach
assertF2sEquals("5.3687091E18", 5.368709E18f);
assertF2sEquals("4.6143166E18", 4.6143165E18f);
assertF2sEquals("0.007812537", 0.007812537f);
assertF2sEquals("1.4E-45", 1.4E-45f);
assertF2sEquals("1.18697725E20", 1.18697724E20f);
assertF2sEquals("1.00014165E-36", 1.00014165E-36f);
assertF2sEquals("200.0", 200f);
assertF2sEquals("3.3554432E7", 3.3554432E7f);
}
}
12 changes: 12 additions & 0 deletions src/test/java/com/fasterxml/jackson/core/io/jdk/JdkDoubleTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.fasterxml.jackson.core.io.jdk;

import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

@RunWith(JUnit4.class)
public class JdkDoubleTest extends DoubleToStringTest {
@Override
String f(double f) {
return Double.toString(f);
}
}
12 changes: 12 additions & 0 deletions src/test/java/com/fasterxml/jackson/core/io/jdk/JdkFloatTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.fasterxml.jackson.core.io.jdk;

import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

@RunWith(JUnit4.class)
public class JdkFloatTest extends FloatToStringTest {
@Override
String f(float f) {
return Float.toString(f);
}
}
Loading