mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
classlib: improve accuracy of Double.toString
This commit is contained in:
parent
7059038cf0
commit
e1706f242d
|
@ -47,7 +47,7 @@ public final class DoubleAnalyzer {
|
||||||
mantissa |= 1L << 52;
|
mantissa |= 1L << 52;
|
||||||
}
|
}
|
||||||
|
|
||||||
int decExponent = Arrays.binarySearch(exp10Table, exponent);
|
int decExponent = Arrays.binarySearch(exp10Table, (short) exponent);
|
||||||
if (decExponent < 0) {
|
if (decExponent < 0) {
|
||||||
decExponent = -decExponent;
|
decExponent = -decExponent;
|
||||||
}
|
}
|
||||||
|
@ -810,7 +810,7 @@ public final class DoubleAnalyzer {
|
||||||
-1468012460592228864L,
|
-1468012460592228864L,
|
||||||
};
|
};
|
||||||
|
|
||||||
private static int[] exp10Table = {
|
static short[] exp10Table = {
|
||||||
-70,
|
-70,
|
||||||
-66,
|
-66,
|
||||||
-63,
|
-63,
|
||||||
|
|
|
@ -26,7 +26,7 @@ public final class DoubleSynthesizer {
|
||||||
}
|
}
|
||||||
|
|
||||||
var binMantissa = DoubleAnalyzer.mulAndShiftRight(mantissa, mantissa10Table[indexInTable], 0);
|
var binMantissa = DoubleAnalyzer.mulAndShiftRight(mantissa, mantissa10Table[indexInTable], 0);
|
||||||
var binExp = exp10Table[indexInTable];
|
int binExp = exp10Table[indexInTable];
|
||||||
|
|
||||||
var binMantissaShift = (64 - Long.numberOfLeadingZeros(binMantissa)) - 58;
|
var binMantissaShift = (64 - Long.numberOfLeadingZeros(binMantissa)) - 58;
|
||||||
if (binMantissaShift >= 0) {
|
if (binMantissaShift >= 0) {
|
||||||
|
@ -39,7 +39,27 @@ public final class DoubleSynthesizer {
|
||||||
if (binExp >= 2047) {
|
if (binExp >= 2047) {
|
||||||
return negative ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
|
return negative ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
|
||||||
}
|
}
|
||||||
binMantissa += 1L << 4;
|
|
||||||
|
var mantissaLowerBits = 5;
|
||||||
|
var mantissaLowerPos = 1 << mantissaLowerBits;
|
||||||
|
var error = (int) (binMantissa & (mantissaLowerPos - 1));
|
||||||
|
var correction = mantissaLowerPos >> 1;
|
||||||
|
if (Math.abs(error - (mantissaLowerPos >>> 1)) <= 1) {
|
||||||
|
var binMantissaWithoutError = binMantissa & -mantissaLowerPos;
|
||||||
|
var low = calcDecMantissa(binMantissaWithoutError, mantissaLowerPos, indexInTable, binExp);
|
||||||
|
var hi = calcDecMantissa(binMantissaWithoutError + mantissaLowerPos, mantissaLowerPos,
|
||||||
|
indexInTable, binExp);
|
||||||
|
low = mantissa - low;
|
||||||
|
hi = hi - mantissa;
|
||||||
|
var cmp = Long.compareUnsigned(low, hi);
|
||||||
|
if (cmp < 0) {
|
||||||
|
correction = -error;
|
||||||
|
} else if (cmp > 0) {
|
||||||
|
correction = mantissaLowerPos - error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
binMantissa += correction;
|
||||||
if ((binMantissa & (-1L << 58L)) != 0) {
|
if ((binMantissa & (-1L << 58L)) != 0) {
|
||||||
binMantissa >>>= 1;
|
binMantissa >>>= 1;
|
||||||
binExp++;
|
binExp++;
|
||||||
|
@ -49,7 +69,7 @@ public final class DoubleSynthesizer {
|
||||||
binExp = 0;
|
binExp = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
binMantissa = (binMantissa >>> 5) & (-1L << 12 >>> 12);
|
binMantissa = (binMantissa >>> mantissaLowerBits) & (-1L << 12 >>> 12);
|
||||||
var iee754 = binMantissa | ((long) binExp << 52);
|
var iee754 = binMantissa | ((long) binExp << 52);
|
||||||
if (negative) {
|
if (negative) {
|
||||||
iee754 ^= 1L << 63;
|
iee754 ^= 1L << 63;
|
||||||
|
@ -57,6 +77,29 @@ public final class DoubleSynthesizer {
|
||||||
return Double.longBitsToDouble(iee754);
|
return Double.longBitsToDouble(iee754);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static long calcDecMantissa(long mantissa, int lowerBit, int indexInTable, int binExp) {
|
||||||
|
var half = lowerBit >>> 1;
|
||||||
|
var shift = 7 - (DoubleAnalyzer.exp10Table[indexInTable] - binExp);
|
||||||
|
var decMantissa = DoubleAnalyzer.mulAndShiftRight(mantissa,
|
||||||
|
DoubleAnalyzer.mantissa10Table[indexInTable], shift);
|
||||||
|
var decMantissaHi = DoubleAnalyzer.mulAndShiftRight(mantissa + half,
|
||||||
|
DoubleAnalyzer.mantissa10Table[indexInTable], shift);
|
||||||
|
var decMantissaLow = DoubleAnalyzer.mulAndShiftRight(mantissa - half,
|
||||||
|
DoubleAnalyzer.mantissa10Table[indexInTable], shift);
|
||||||
|
|
||||||
|
var lowerPos = DoubleAnalyzer.findLowerDistance(decMantissa, decMantissaLow);
|
||||||
|
var upperPos = DoubleAnalyzer.findUpperDistance(decMantissa, decMantissaHi);
|
||||||
|
var posCmp = Long.compareUnsigned(lowerPos, upperPos);
|
||||||
|
if (posCmp > 0) {
|
||||||
|
decMantissa = Long.divideUnsigned(decMantissa, lowerPos) * lowerPos;
|
||||||
|
} else if (posCmp < 0) {
|
||||||
|
decMantissa = Long.divideUnsigned(decMantissa, upperPos) * upperPos + upperPos;
|
||||||
|
} else {
|
||||||
|
decMantissa = Long.divideUnsigned(decMantissa + (upperPos / 2), upperPos) * upperPos;
|
||||||
|
}
|
||||||
|
return decMantissa;
|
||||||
|
}
|
||||||
|
|
||||||
// Numbers in the table below are generated by DoubleSynthesizerGenerator
|
// Numbers in the table below are generated by DoubleSynthesizerGenerator
|
||||||
|
|
||||||
private static final long[] mantissa10Table = {
|
private static final long[] mantissa10Table = {
|
||||||
|
@ -722,7 +765,7 @@ public final class DoubleSynthesizer {
|
||||||
-8425902273664687726L,
|
-8425902273664687726L,
|
||||||
};
|
};
|
||||||
|
|
||||||
private static int[] exp10Table = {
|
private static short[] exp10Table = {
|
||||||
-76,
|
-76,
|
||||||
-72,
|
-72,
|
||||||
-69,
|
-69,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user