classlib: fix parsing floats and doubles with large exponents

This commit is contained in:
Alexey Andreev 2024-09-05 09:08:53 +02:00
parent a9d46ac55e
commit b36f38f48f
4 changed files with 10 additions and 2 deletions

View File

@ -21,9 +21,12 @@ public final class DoubleSynthesizer {
public static double synthesizeDouble(long mantissa, int exp, boolean negative) { public static double synthesizeDouble(long mantissa, int exp, boolean negative) {
var indexInTable = DoubleAnalyzer.MAX_ABS_DEC_EXP + exp; var indexInTable = DoubleAnalyzer.MAX_ABS_DEC_EXP + exp;
if (mantissa == 0 || indexInTable > mantissa10Table.length || indexInTable < 0) { if (mantissa == 0 || indexInTable < 0) {
return Double.longBitsToDouble(negative ? (1L << 63) : 0); return Double.longBitsToDouble(negative ? (1L << 63) : 0);
} }
if (indexInTable >= mantissa10Table.length) {
return negative ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
}
var binMantissa = DoubleAnalyzer.mulAndShiftRight(mantissa, mantissa10Table[indexInTable], 0); var binMantissa = DoubleAnalyzer.mulAndShiftRight(mantissa, mantissa10Table[indexInTable], 0);
int binExp = exp10Table[indexInTable]; int binExp = exp10Table[indexInTable];

View File

@ -21,9 +21,12 @@ public final class FloatSynthesizer {
public static float synthesizeFloat(int mantissa, int exp, boolean negative) { public static float synthesizeFloat(int mantissa, int exp, boolean negative) {
var indexInTable = FloatAnalyzer.MAX_ABS_DEC_EXP + exp; var indexInTable = FloatAnalyzer.MAX_ABS_DEC_EXP + exp;
if (mantissa == 0 || indexInTable > mantissa10Table.length || indexInTable < 0) { if (mantissa == 0 || indexInTable < 0) {
return Float.intBitsToFloat(negative ? (1 << 31) : 0); return Float.intBitsToFloat(negative ? (1 << 31) : 0);
} }
if (indexInTable >= mantissa10Table.length) {
return negative ? Float.NEGATIVE_INFINITY : Float.POSITIVE_INFINITY;
}
var binMantissa = FloatAnalyzer.mulAndShiftRight(mantissa, mantissa10Table[indexInTable], 0); var binMantissa = FloatAnalyzer.mulAndShiftRight(mantissa, mantissa10Table[indexInTable], 0);
var binExp = exp10Table[indexInTable] - 1; var binExp = exp10Table[indexInTable] - 1;

View File

@ -57,6 +57,7 @@ public class DoubleTest {
assertEquals(4499999999999888888888888.0, Double.parseDouble("4499999999999888888888888"), 1E9); assertEquals(4499999999999888888888888.0, Double.parseDouble("4499999999999888888888888"), 1E9);
assertEquals(0.4499999999999888888888888, Double.parseDouble("0.4499999999999888888888888"), 1E-15); assertEquals(0.4499999999999888888888888, Double.parseDouble("0.4499999999999888888888888"), 1E-15);
assertEquals(Double.POSITIVE_INFINITY, Double.parseDouble("1e330"), 1E-15);
} }
@Test @Test

View File

@ -55,6 +55,7 @@ public class FloatTest {
assertEquals(0, Float.parseFloat("00000.0000"), 1E-12F); assertEquals(0, Float.parseFloat("00000.0000"), 1E-12F);
assertEquals(4499999285F, Float.parseFloat("4499999285"), 100F); assertEquals(4499999285F, Float.parseFloat("4499999285"), 100F);
assertEquals(0.4499999285F, Float.parseFloat("0.4499999285"), 1E-9F); assertEquals(0.4499999285F, Float.parseFloat("0.4499999285"), 1E-9F);
assertEquals(Float.POSITIVE_INFINITY, Float.parseFloat("1e50"), 1E-9F);
} }
@Test @Test