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

View File

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