classlib: improve accuracy of double parser

This commit is contained in:
Alexey Andreev 2023-09-14 15:38:43 +02:00
parent 0a92994c4b
commit 7059038cf0
3 changed files with 1353 additions and 1351 deletions

View File

@ -94,7 +94,7 @@ public final class DoubleAnalyzer {
result.exponent = decExponent - MAX_ABS_DEC_EXP; result.exponent = decExponent - MAX_ABS_DEC_EXP;
} }
private static long findLowerDistance(long mantissa, long lower) { static long findLowerDistance(long mantissa, long lower) {
long pos = 1; long pos = 1;
while (Long.compareUnsigned( while (Long.compareUnsigned(
Long.divideUnsigned(mantissa, pos * 10), Long.divideUnsigned(mantissa, pos * 10),
@ -104,7 +104,7 @@ public final class DoubleAnalyzer {
return pos; return pos;
} }
private static long findUpperDistance(long mantissa, long upper) { static long findUpperDistance(long mantissa, long upper) {
long pos = 1; long pos = 1;
while (Long.compareUnsigned( while (Long.compareUnsigned(
Long.divideUnsigned(mantissa, pos * 10), Long.divideUnsigned(mantissa, pos * 10),
@ -147,7 +147,7 @@ public final class DoubleAnalyzer {
// Numbers in the table below are generated by DoubleAnalyzerGenerator // Numbers in the table below are generated by DoubleAnalyzerGenerator
private static long[] mantissa10Table = { static long[] mantissa10Table = {
-9023189732560287392L, -9023189732560287392L,
-3369057127870728857L, -3369057127870728857L,
-6384594517038493409L, -6384594517038493409L,

View File

@ -24,29 +24,26 @@ public final class DoubleSynthesizerGenerator {
public static void main(String[] args) { public static void main(String[] args) {
var mantissaList = new long[660]; var mantissaList = new long[660];
var expList = new long[660]; var expList = new long[660];
var shift = 122;
var exp = 0; var binOneShift = 1024 + 256;
var binOne = BigInteger.ONE.shiftLeft(binOneShift);
var dec = BigInteger.valueOf(1000000000000000000L); var dec = BigInteger.valueOf(1000000000000000000L);
for (var i = 0; i < 330; ++i) { for (var i = 0; i <= 330; ++i) {
while (BigInteger.ONE.shiftLeft(shift + exp + 1).divide(dec).bitLength() <= 64) { var quot = binOne.divide(dec);
++exp; mantissaList[330 - i] = extractLong(quot);
} var exp = quot.bitLength() - binOneShift + 57;
mantissaList[330 + i] = BigInteger.ONE.shiftLeft(shift + exp).divide(dec).longValue(); expList[330 - i] = 1023 + exp;
dec = dec.multiply(BigInteger.valueOf(10)); dec = dec.multiply(BigInteger.valueOf(10));
expList[330 + i] = 1023 - exp;
} }
exp = 1; dec = BigInteger.valueOf(1000000000000000000L);
dec = BigInteger.valueOf(1000000000000000000L).multiply(BigInteger.ONE.shiftLeft(1024)); var q = BigInteger.TEN;
var q = BigInteger.valueOf(10L); for (var i = 1; i < 330; ++i) {
for (var i = 1; i <= 330; ++i) { var quot = q.shiftLeft(binOneShift).divide(dec);
while (BigInteger.ONE.shiftLeft(shift + 1024 - exp).multiply(q).divide(dec).bitLength() > 64) { mantissaList[330 + i] = extractLong(quot);
++exp; var exp = quot.bitLength() - binOneShift + 57;
} expList[330 + i] = 1023 + exp;
mantissaList[330 - i] = BigInteger.ONE.shiftLeft(shift + 1024 - exp).multiply(q).divide(dec).longValue(); q = q.multiply(BigInteger.TEN);
q = q.multiply(BigInteger.valueOf(10));
expList[330 - i] = 1023 + exp;
} }
System.out.println("[mantissa]"); System.out.println("[mantissa]");
@ -60,4 +57,8 @@ public final class DoubleSynthesizerGenerator {
System.out.println(value + ","); System.out.println(value + ",");
} }
} }
private static long extractLong(BigInteger n) {
return n.shiftRight(n.bitLength() - 65).add(BigInteger.ONE).shiftRight(1).longValue();
}
} }