diff --git a/libc/src/__support/FPUtil/double_double.h b/libc/src/__support/FPUtil/double_double.h --- a/libc/src/__support/FPUtil/double_double.h +++ b/libc/src/__support/FPUtil/double_double.h @@ -11,13 +11,17 @@ #include "multiply_add.h" #include "src/__support/common.h" +#include "src/__support/macros/properties/cpu_features.h" // LIBC_TARGET_CPU_HAS_FMA #include "src/__support/number_pair.h" namespace __llvm_libc::fputil { using DoubleDouble = __llvm_libc::NumberPair; -// Assumption: |a| >= |b| +// The output of Dekker's FastTwoSum algorithm is correct, i.e.: +// r.hi + r.lo = a + b exactly +// and |r.lo| < eps(r.lo) +// if ssumption: |a| >= |b|, or a = 0. LIBC_INLINE constexpr DoubleDouble exact_add(double a, double b) { DoubleDouble r{0.0, 0.0}; r.hi = a + b; @@ -39,12 +43,43 @@ return exact_add(r.hi, r.lo + a.lo); } -// TODO(lntue): add a correct multiplication when FMA instructions are not -// available. +// Velkamp's Splitting for double precision. +LIBC_INLINE constexpr DoubleDouble split(double a) { + DoubleDouble r{0.0, 0.0}; + // Splitting constant = 2^ceil(prec(double)/2) + 1 = 2^27 + 1. + constexpr double C = 0x1.0p27 + 1.0; + double t1 = C * a; + double t2 = a - t1; + r.hi = t1 + t2; + r.lo = a - r.hi; + return r; +} + LIBC_INLINE DoubleDouble exact_mult(double a, double b) { DoubleDouble r{0.0, 0.0}; + +#ifdef LIBC_TARGET_CPU_HAS_FMA r.hi = a * b; r.lo = fputil::multiply_add(a, b, -r.hi); +#else + // Dekker's Product. + DoubleDouble as = split(a); + DoubleDouble bs = split(b); + r.hi = a * b; + double t1 = as.hi * bs.hi - r.hi; + double t2 = as.hi * bs.lo + t1; + double t3 = as.lo * bs.hi + t2; + r.lo = as.lo * bs.lo + t3; +#endif // LIBC_TARGET_CPU_HAS_FMA + + return r; +} + +LIBC_INLINE DoubleDouble quick_mult(DoubleDouble a, DoubleDouble b) { + DoubleDouble r = exact_mult(a.hi, b.hi); + double t1 = fputil::multiply_add(a.hi, b.lo, r.lo); + double t2 = fputil::multiply_add(a.lo, b.hi, t1); + r.lo = t2; return r; } diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt --- a/libc/src/math/generic/CMakeLists.txt +++ b/libc/src/math/generic/CMakeLists.txt @@ -764,9 +764,10 @@ common_constants.h SRCS common_constants.cpp + DEPENDS + libc.src.__support.number_pair ) -# TODO(lntue): Make log10 correctly rounded for non-FMA targets. add_entrypoint_object( log10 SRCS @@ -774,9 +775,11 @@ HDRS ../log10.h DEPENDS + .common_constants libc.src.__support.FPUtil.fenv_impl libc.src.__support.FPUtil.fp_bits libc.src.__support.FPUtil.multiply_add + libc.src.__support.FPUtil.polyeval libc.src.__support.FPUtil.double_double libc.src.__support.FPUtil.dyadic_float libc.src.__support.macros.optimization diff --git a/libc/src/math/generic/common_constants.h b/libc/src/math/generic/common_constants.h --- a/libc/src/math/generic/common_constants.h +++ b/libc/src/math/generic/common_constants.h @@ -9,6 +9,8 @@ #ifndef LLVM_LIBC_SRC_MATH_GENERIC_COMMON_CONSTANTS_H #define LLVM_LIBC_SRC_MATH_GENERIC_COMMON_CONSTANTS_H +#include "src/__support/number_pair.h" + namespace __llvm_libc { // Lookup table for (1/f) where f = 1 + n*2^(-7), n = 0..127. @@ -23,8 +25,26 @@ // Lookup table for range reduction constants r for logarithms. extern const double RD[128]; +// Lookup table for compensated constants for exact range reduction when FMA +// instructions are not available. +extern const double CD[128]; + // Lookup table for -log(r) extern const double LOG_R[128]; +extern const NumberPair LOG_R_DD[128]; + +// Minimax polynomial for (log(1 + x) - x)/x^2, generated by sollya with: +// > P = fpminimax((log(1 + x) - x)/x^2, 5, [|D...|], [-2^-8, 2^-7]); +constexpr double LOG_COEFFS[6] = {-0x1.fffffffffffffp-2, 0x1.5555555554a9bp-2, + -0x1.0000000094567p-2, 0x1.99999dcc9823cp-3, + -0x1.55550ac2e537ap-3, 0x1.21a02c4e624d7p-3}; + +// log(2) generated by Sollya with: +// > a = 2^-43 * nearestint(2^43*log(2)); +// LSB = 2^-43 is chosen so that e_x * LOG_2_HI is exact for -1075 < e_x < 1024. +constexpr double LOG_2_HI = 0x1.62e42fefa38p-1; // LSB = 2^-43 +// > b = round(log10(2) - a, D, RN); +constexpr double LOG_2_LO = 0x1.ef35793c7673p-45; // LSB = 2^-97 // Lookup table for exp(m) with m = -104, ..., 89. // -104 = floor(log(single precision's min denormal)) diff --git a/libc/src/math/generic/common_constants.cpp b/libc/src/math/generic/common_constants.cpp --- a/libc/src/math/generic/common_constants.cpp +++ b/libc/src/math/generic/common_constants.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "common_constants.h" +#include "src/__support/number_pair.h" namespace __llvm_libc { @@ -151,6 +152,35 @@ 0x1.0ap-1, 0x1.08p-1, 0x1.08p-1, 0x1.06p-1, 0x1.06p-1, 0x1.04p-1, 0x1.04p-1, 0x1.02p-1, 0x1.0p-1}; +// Compensated constants for exact logarithm range reduction when FMA is not +// available. +// Generated by Sollya with the formula: CD[i] = RD[i]*(1 + i*2^-7) - 1 +// for RD[i] defined on the table above. +alignas(64) const double CD[128] = { + 0.0, -0x1p-14, -0x1p-12, -0x1.2p-11, -0x1p-10, -0x1.9p-10, + -0x1.2p-9, -0x1.88p-9, -0x1p-8, -0x1.9p-11, -0x1.fp-10, -0x1.9cp-9, + -0x1p-12, -0x1.cp-10, -0x1.bp-9, -0x1.5p-11, -0x1.4p-9, 0x1p-14, + -0x1p-9, 0x1.ap-12, -0x1.ep-10, 0x1.8p-12, -0x1.1p-9, -0x1p-15, + -0x1.6p-9, -0x1.ap-11, -0x1.ep-9, -0x1.f8p-10, -0x1p-12, -0x1.cp-9, + -0x1.fp-10, -0x1.cp-12, -0x1p-8, -0x1.54p-9, -0x1.6p-10, -0x1.4p-13, + 0x1p-10, -0x1.88p-9, -0x1.08p-9, -0x1.2p-10, -0x1p-12, 0x1.2p-11, + -0x1p-8, -0x1.acp-9, -0x1.6p-9, -0x1.1cp-9, -0x1.cp-10, -0x1.58p-10, + -0x1p-10, -0x1.7p-11, -0x1p-11, -0x1.6p-12, -0x1p-12, -0x1.cp-13, + -0x1p-12, -0x1.6p-12, -0x1p-11, -0x1.7p-11, -0x1p-10, -0x1.58p-10, + -0x1.cp-10, -0x1.1cp-9, -0x1.6p-9, -0x1.acp-9, -0x1p-8, 0x1.5p-10, + 0x1.2p-11, -0x1p-12, -0x1.2p-10, -0x1.08p-9, -0x1.88p-9, 0x1.0cp-9, + 0x1p-10, -0x1.4p-13, -0x1.6p-10, -0x1.54p-9, -0x1p-8, 0x1p-10, + -0x1.cp-12, -0x1.fp-10, -0x1.cp-9, 0x1.68p-10, -0x1p-12, -0x1.f8p-10, + -0x1.ep-9, 0x1.1p-10, -0x1.ap-11, -0x1.6p-9, 0x1p-9, -0x1p-15, + -0x1.1p-9, 0x1.48p-9, 0x1.8p-12, -0x1.ep-10, 0x1.6p-9, 0x1.ap-12, + -0x1p-9, 0x1.48p-9, 0x1p-14, -0x1.4p-9, 0x1p-9, -0x1.5p-11, + -0x1.bp-9, 0x1.1p-10, -0x1.cp-10, 0x1.54p-9, -0x1p-12, -0x1.9cp-9, + 0x1.2p-10, -0x1.fp-10, 0x1.3p-9, -0x1.9p-11, -0x1p-8, 0x1p-12, + -0x1.88p-9, 0x1.28p-10, -0x1.2p-9, 0x1.fp-10, -0x1.9p-10, 0x1.4cp-9, + -0x1p-10, 0x1.9p-9, -0x1.2p-11, 0x1.c4p-9, -0x1p-12, 0x1.e8p-9, + -0x1p-14, -0x1p-8, +}; + alignas(64) const double LOG_R[128] = { 0x0.0000000000000p0, 0x1.010157588de71p-7, 0x1.0205658935847p-6, 0x1.8492528c8cabfp-6, 0x1.0415d89e74444p-5, 0x1.466aed42de3eap-5, @@ -196,6 +226,145 @@ 0x1.5707a26bb8c66p-1, 0x1.5af405c3649ep-1, 0x1.5af405c3649ep-1, 0x1.5ee82aa24192p-1, 0x0.000000000000p0}; +// Generated by Sollya with: +// for i from 0 to 127 do { +// r = 2^-8 * ceil( 2^8 * (1 - 2^(-8)) / (1 + i*2^-7) ); +// b = nearestint(log(r)*2^43) * 2^-43; +// c = round(log(r) - b, D, RN); +// print("{", -c, ",", -b, "},"); +// }; +// We replace LOG_R[0] with log10(1.0) == 0.0 +alignas(64) const NumberPair LOG_R_DD[128] = { + {0.0, 0.0}, + {-0x1.0c76b999d2be8p-46, 0x1.010157589p-7}, + {-0x1.3dc5b06e2f7d2p-45, 0x1.0205658938p-6}, + {-0x1.aa0ba325a0c34p-45, 0x1.8492528c9p-6}, + {0x1.111c05cf1d753p-47, 0x1.0415d89e74p-5}, + {-0x1.c167375bdfd28p-45, 0x1.466aed42ep-5}, + {-0x1.97995d05a267dp-46, 0x1.894aa149fcp-5}, + {-0x1.a68f247d82807p-46, 0x1.ccb73cdddcp-5}, + {-0x1.7e5dd7009902cp-46, 0x1.08598b59e4p-4}, + {-0x1.5325d560d9e9bp-45, 0x1.1973bd1466p-4}, + {0x1.cc85ea5db4ed7p-45, 0x1.3bdf5a7d1ep-4}, + {-0x1.c69063c5d1d1ep-45, 0x1.5e95a4d97ap-4}, + {0x1.c1e8da99ded32p-49, 0x1.700d30aeacp-4}, + {0x1.3115c3abd47dap-45, 0x1.9335e5d594p-4}, + {-0x1.390802bf768e5p-46, 0x1.b6ac88dad6p-4}, + {0x1.646d1c65aacd3p-45, 0x1.c885801bc4p-4}, + {-0x1.dc068afe645ep-45, 0x1.ec739830a2p-4}, + {-0x1.534d64fa10afdp-45, 0x1.fe89139dbep-4}, + {0x1.1ef78ce2d07f2p-45, 0x1.1178e8227ep-3}, + {0x1.ca78e44389934p-45, 0x1.1aa2b7e23fp-3}, + {0x1.39d6ccb81b4a1p-47, 0x1.2d1610c868p-3}, + {0x1.62fa8234b7289p-51, 0x1.365fcb0159p-3}, + {0x1.5837954fdb678p-45, 0x1.4913d8333bp-3}, + {0x1.633e8e5697dc7p-45, 0x1.527e5e4a1bp-3}, + {0x1.9cf8b2c3c2e78p-46, 0x1.6574ebe8c1p-3}, + {-0x1.5118de59c21e1p-45, 0x1.6f0128b757p-3}, + {0x1.e0ddb9a631e83p-46, 0x1.823c16551ap-3}, + {-0x1.73d54aae92cd1p-47, 0x1.8beafeb39p-3}, + {0x1.7f22858a0ff6fp-47, 0x1.95a5adcf7p-3}, + {-0x1.8724350562169p-45, 0x1.a93ed3c8aep-3}, + {-0x1.c358d4eace1aap-47, 0x1.b31d8575bdp-3}, + {-0x1.d4bc4595412b6p-45, 0x1.bd087383bep-3}, + {-0x1.84a7e75b6f6e4p-47, 0x1.d1037f2656p-3}, + {-0x1.aff2af715b035p-45, 0x1.db13db0d49p-3}, + {0x1.212276041f43p-51, 0x1.e530effe71p-3}, + {-0x1.a211565bb8e11p-51, 0x1.ef5ade4ddp-3}, + {0x1.bcbecca0cdf3p-46, 0x1.f991c6cb3bp-3}, + {0x1.89cdb16ed4e91p-48, 0x1.07138604d58p-2}, + {0x1.7188b163ceae9p-45, 0x1.0c42d67616p-2}, + {-0x1.c210e63a5f01cp-45, 0x1.1178e8227e8p-2}, + {0x1.b9acdf7a51681p-45, 0x1.16b5ccbacf8p-2}, + {0x1.ca6ed5147bdb7p-45, 0x1.1bf99635a68p-2}, + {0x1.c93c1df5bb3b6p-45, 0x1.269621134d8p-2}, + {0x1.a9cfa4a5004f4p-45, 0x1.2bef07cdc9p-2}, + {-0x1.8e27ad3213cb8p-45, 0x1.314f1e1d36p-2}, + {0x1.16ecdb0f177c8p-46, 0x1.36b6776be1p-2}, + {0x1.83b54b606bd5cp-46, 0x1.3c25277333p-2}, + {0x1.8e436ec90e09dp-47, 0x1.419b423d5e8p-2}, + {-0x1.f27ce0967d675p-45, 0x1.4718dc271c8p-2}, + {-0x1.e20891b0ad8a4p-45, 0x1.4c9e09e173p-2}, + {0x1.ebe708164c759p-45, 0x1.522ae0738ap-2}, + {0x1.fadedee5d40efp-46, 0x1.57bf753c8dp-2}, + {-0x1.a0b2a08a465dcp-47, 0x1.5d5bddf596p-2}, + {-0x1.db623e731aep-45, 0x1.630030b3abp-2}, + {0x1.0a0d32756ebap-45, 0x1.68ac83e9c68p-2}, + {0x1.721657c222d87p-46, 0x1.6e60ee6af18p-2}, + {0x1.d8b0949dc60b3p-45, 0x1.741d876c678p-2}, + {0x1.9ec7d2efd1778p-45, 0x1.79e26687cf8p-2}, + {-0x1.72090c812566ap-45, 0x1.7fafa3bd818p-2}, + {0x1.fd56f3333778ap-45, 0x1.85855776dc8p-2}, + {-0x1.05ae1e5e7047p-45, 0x1.8b639a88b3p-2}, + {-0x1.766b52ee6307dp-46, 0x1.914a8635bf8p-2}, + {-0x1.52313a502d9fp-46, 0x1.973a3431358p-2}, + {-0x1.6279e10d0c0bp-45, 0x1.9d32bea15fp-2}, + {0x1.3c6457f9d79f5p-45, 0x1.a33440224f8p-2}, + {0x1.3c6457f9d79f5p-45, 0x1.a33440224f8p-2}, + {0x1.e36f2bea77a5dp-46, 0x1.a93ed3c8ad8p-2}, + {-0x1.17cc552774458p-45, 0x1.af5295248dp-2}, + {0x1.095252d841995p-46, 0x1.b56fa044628p-2}, + {0x1.7d85bf40a666dp-45, 0x1.bb9611b80ep-2}, + {0x1.cec807fe8e18p-45, 0x1.c1c60693fap-2}, + {0x1.cec807fe8e18p-45, 0x1.c1c60693fap-2}, + {-0x1.9b6ddc15249aep-45, 0x1.c7ff9c74558p-2}, + {-0x1.797c33ec7a6bp-47, 0x1.ce42f180648p-2}, + {0x1.35bafe9a767a8p-45, 0x1.d490246def8p-2}, + {-0x1.ea42d60dc616ap-46, 0x1.dae75484c98p-2}, + {-0x1.326b207322938p-46, 0x1.e148a1a2728p-2}, + {-0x1.326b207322938p-46, 0x1.e148a1a2728p-2}, + {-0x1.465505372bd08p-45, 0x1.e7b42c3ddbp-2}, + {0x1.f27f45a470251p-45, 0x1.ee2a156b41p-2}, + {0x1.2cde56f014a8bp-46, 0x1.f4aa7ee0318p-2}, + {0x1.2cde56f014a8bp-46, 0x1.f4aa7ee0318p-2}, + {0x1.085fa3c164935p-47, 0x1.fb358af7a48p-2}, + {-0x1.53ba3b1727b1cp-47, 0x1.00e5ae5b208p-1}, + {-0x1.4c45fe79539ep-47, 0x1.04360be7604p-1}, + {-0x1.4c45fe79539ep-47, 0x1.04360be7604p-1}, + {0x1.6812241edf5fdp-45, 0x1.078bf0533c4p-1}, + {0x1.f486b887e7e27p-46, 0x1.0ae76e2d054p-1}, + {0x1.f486b887e7e27p-46, 0x1.0ae76e2d054p-1}, + {0x1.c299807801742p-46, 0x1.0e4898611ccp-1}, + {-0x1.58647bb9ddcb2p-45, 0x1.11af823c75cp-1}, + {-0x1.58647bb9ddcb2p-45, 0x1.11af823c75cp-1}, + {-0x1.edd97a293ae49p-45, 0x1.151c3f6f298p-1}, + {0x1.4cc4ef8ab465p-46, 0x1.188ee40f23cp-1}, + {0x1.4cc4ef8ab465p-46, 0x1.188ee40f23cp-1}, + {0x1.cacdeed70e667p-51, 0x1.1c07849ae6p-1}, + {-0x1.a7242c9fe81d3p-45, 0x1.1f8635fc618p-1}, + {-0x1.a7242c9fe81d3p-45, 0x1.1f8635fc618p-1}, + {0x1.2fc066e48667bp-46, 0x1.230b0d8bebcp-1}, + {-0x1.b61f10522625p-47, 0x1.269621134dcp-1}, + {-0x1.b61f10522625p-47, 0x1.269621134dcp-1}, + {0x1.06d2be797882dp-45, 0x1.2a2786d0ecp-1}, + {-0x1.7a6e507b9dc11p-46, 0x1.2dbf557b0ep-1}, + {-0x1.7a6e507b9dc11p-46, 0x1.2dbf557b0ep-1}, + {-0x1.74e93c5a0ed9cp-45, 0x1.315da443408p-1}, + {-0x1.74e93c5a0ed9cp-45, 0x1.315da443408p-1}, + {0x1.0b83f9527e6acp-46, 0x1.35028ad9d8cp-1}, + {-0x1.18b7abb5569a4p-45, 0x1.38ae2171978p-1}, + {-0x1.18b7abb5569a4p-45, 0x1.38ae2171978p-1}, + {-0x1.2b7367cfe13c2p-47, 0x1.3c6080c36cp-1}, + {-0x1.2b7367cfe13c2p-47, 0x1.3c6080c36cp-1}, + {-0x1.6ce7930f0c74cp-45, 0x1.4019c2125ccp-1}, + {-0x1.d984f481051f7p-48, 0x1.43d9ff2f924p-1}, + {-0x1.d984f481051f7p-48, 0x1.43d9ff2f924p-1}, + {-0x1.2cb6af94d60aap-45, 0x1.47a1527e8a4p-1}, + {-0x1.2cb6af94d60aap-45, 0x1.47a1527e8a4p-1}, + {0x1.f7115ed4c541cp-49, 0x1.4b6fd6f970cp-1}, + {0x1.f7115ed4c541cp-49, 0x1.4b6fd6f970cp-1}, + {-0x1.e6c516d93b8fbp-45, 0x1.4f45a835a5p-1}, + {-0x1.e6c516d93b8fbp-45, 0x1.4f45a835a5p-1}, + {0x1.5ccc45d257531p-47, 0x1.5322e268678p-1}, + {0x1.5ccc45d257531p-47, 0x1.5322e268678p-1}, + {0x1.9980bff3303ddp-47, 0x1.5707a26bb8cp-1}, + {0x1.9980bff3303ddp-47, 0x1.5707a26bb8cp-1}, + {0x1.dfa63ac10c9fbp-45, 0x1.5af405c3648p-1}, + {0x1.dfa63ac10c9fbp-45, 0x1.5af405c3648p-1}, + {0x1.202380cda46bep-45, 0x1.5ee82aa2418p-1}, + {0.0, 0.0}, +}; + // Lookup table for exp(m) with m = -104, ..., 89. // -104 = floor(log(single precision's min denormal)) // 89 = ceil(log(single precision's max normal)) diff --git a/libc/src/math/generic/log10.cpp b/libc/src/math/generic/log10.cpp --- a/libc/src/math/generic/log10.cpp +++ b/libc/src/math/generic/log10.cpp @@ -9,945 +9,858 @@ #include "src/math/log10.h" #include "src/__support/FPUtil/FEnvImpl.h" #include "src/__support/FPUtil/FPBits.h" +#include "src/__support/FPUtil/PolyEval.h" #include "src/__support/FPUtil/double_double.h" #include "src/__support/FPUtil/dyadic_float.h" #include "src/__support/FPUtil/multiply_add.h" #include "src/__support/common.h" #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY +#include "common_constants.h" + namespace __llvm_libc { -// 192-bit precision dyadic floating point numbers. -using Float192 = typename fputil::DyadicFloat<192>; -using MType = typename Float192::MantissaType; +// 128-bit precision dyadic floating point numbers. +using Float128 = typename fputil::DyadicFloat<128>; +using MType = typename Float128::MantissaType; namespace { -// log10(2) generated by Sollya with: -// > a = round(log10(2), 43, RN); -constexpr double LOG10_2_HI = 0x1.34413509f78p-2; // LSB = 2^-43 -// > b = round(log10(2) - a, D, RN); -constexpr double LOG10_2_LO = 0x1.fef311f12b358p-46; // LSB = 2^-98 -constexpr double LOG10_2_ULP[2] = {0x1.0p-97, 0.0}; - -// Generated by Sollya with: -// > for i from 0 to 127 do { -// r = 2^-8 * nearestint( 2^8 * (1 + (i + 0.5)*2^(-7) - 2^(-15)) / -// ((1 + i*2^-7)*(1 + (i + 1)*2^-7)) ); -// print(r, ","); -// }; -// To improve the accuracy with inputs close to 1, we replace R[0] with 1.0. -constexpr double R[128] = { - 1.0, 0x1.fap-1, 0x1.f6p-1, 0x1.f2p-1, 0x1.eep-1, 0x1.eap-1, 0x1.e8p-1, - 0x1.e4p-1, 0x1.ep-1, 0x1.dcp-1, 0x1.dap-1, 0x1.d6p-1, 0x1.d2p-1, 0x1.dp-1, - 0x1.ccp-1, 0x1.c8p-1, 0x1.c6p-1, 0x1.c2p-1, 0x1.cp-1, 0x1.bcp-1, 0x1.bap-1, - 0x1.b6p-1, 0x1.b4p-1, 0x1.bp-1, 0x1.aep-1, 0x1.aap-1, 0x1.a8p-1, 0x1.a6p-1, - 0x1.a2p-1, 0x1.ap-1, 0x1.9ep-1, 0x1.9ap-1, 0x1.98p-1, 0x1.96p-1, 0x1.94p-1, - 0x1.9p-1, 0x1.8ep-1, 0x1.8cp-1, 0x1.8ap-1, 0x1.88p-1, 0x1.84p-1, 0x1.82p-1, - 0x1.8p-1, 0x1.7ep-1, 0x1.7cp-1, 0x1.7ap-1, 0x1.78p-1, 0x1.76p-1, 0x1.74p-1, - 0x1.72p-1, 0x1.7p-1, 0x1.6ep-1, 0x1.6cp-1, 0x1.6ap-1, 0x1.68p-1, 0x1.66p-1, - 0x1.64p-1, 0x1.62p-1, 0x1.6p-1, 0x1.5ep-1, 0x1.5cp-1, 0x1.5ap-1, 0x1.58p-1, - 0x1.56p-1, 0x1.54p-1, 0x1.52p-1, 0x1.5p-1, 0x1.5p-1, 0x1.4ep-1, 0x1.4cp-1, - 0x1.4ap-1, 0x1.48p-1, 0x1.46p-1, 0x1.46p-1, 0x1.44p-1, 0x1.42p-1, 0x1.4p-1, - 0x1.3ep-1, 0x1.3ep-1, 0x1.3cp-1, 0x1.3ap-1, 0x1.38p-1, 0x1.38p-1, 0x1.36p-1, - 0x1.34p-1, 0x1.32p-1, 0x1.32p-1, 0x1.3p-1, 0x1.2ep-1, 0x1.2ep-1, 0x1.2cp-1, - 0x1.2ap-1, 0x1.2ap-1, 0x1.28p-1, 0x1.26p-1, 0x1.26p-1, 0x1.24p-1, 0x1.22p-1, - 0x1.22p-1, 0x1.2p-1, 0x1.1ep-1, 0x1.1ep-1, 0x1.1cp-1, 0x1.1cp-1, 0x1.1ap-1, - 0x1.18p-1, 0x1.18p-1, 0x1.16p-1, 0x1.16p-1, 0x1.14p-1, 0x1.12p-1, 0x1.12p-1, - 0x1.1p-1, 0x1.1p-1, 0x1.0ep-1, 0x1.0ep-1, 0x1.0cp-1, 0x1.0ap-1, 0x1.0ap-1, - 0x1.08p-1, 0x1.08p-1, 0x1.06p-1, 0x1.06p-1, 0x1.04p-1, 0x1.04p-1, 0x1.02p-1, - 0x1.02p-1, 0x1p-1, -}; - -// Generated by Sollya with: -// for i from 0 to 127 do { -// r = 2^-8 * nearestint( 2^8 * (1 + (i + 0.5)*2^(-7) - 2^(-15)) / -// ((1 + i*2^-7)*(1 + (i + 1)*2^-7)) ); -// b = nearestint(log10(r)*2^43) * 2^-43; -// c = round(log10(r) - b, D, RN); -// print("{", -c, ",", -b, "},"); -// }; -// We replace LOG10_R[0] with log10(1.0) == 0.0 -constexpr fputil::DoubleDouble LOG10_R[128] = { - {0.0, 0.0}, - {-0x1.dfa6d47e47379p-45, 0x1.4f8205236p-8}, - {-0x1.11bc6f2b9a3acp-45, 0x1.18b2dc8d3p-7}, - {-0x1.685fc114e61bfp-46, 0x1.8a8c06bb2p-7}, - {0x1.3c757d5b7376ap-45, 0x1.fd503c39p-7}, - {0x1.f3cbd9c5111b1p-47, 0x1.3881a7b818p-6}, - {-0x1.e22fab794a816p-45, 0x1.559bd2407p-6}, - {0x1.421bab5f034a4p-45, 0x1.902c31d628p-6}, - {0x1.fedb4b594a31bp-45, 0x1.cb38fccd88p-6}, - {-0x1.c4e824b246c7fp-47, 0x1.0362241e64p-5}, - {-0x1.df23ed2ebe477p-45, 0x1.125d0432ecp-5}, - {-0x1.00c12f7a1b586p-47, 0x1.30838cdc3p-5}, - {0x1.e5ff3439d368dp-46, 0x1.4eec0e2458p-5}, - {0x1.2951bb9cd2fb7p-45, 0x1.5e3966b7e8p-5}, - {0x1.fae96a708581ep-46, 0x1.7d070145f4p-5}, - {0x1.badcf3d6e4566p-46, 0x1.9c197abfp-5}, - {-0x1.b0197d2cb982ep-48, 0x1.abbcebd85p-5}, - {-0x1.24b4a6b5ce4d4p-52, 0x1.cb38fccd8cp-5}, - {-0x1.40bcd23c3e44cp-45, 0x1.db11ed766cp-5}, - {-0x1.024e9d08ce301p-45, 0x1.fafa6d398p-5}, - {0x1.77c3e779b9fcfp-48, 0x1.0585283764p-4}, - {0x1.a9a57734f2038p-48, 0x1.15b11a094ap-4}, - {-0x1.d227d61f9e88dp-45, 0x1.1dd5460c8cp-4}, - {0x1.d288560689912p-53, 0x1.2e3a740b78p-4}, - {-0x1.df5de49ddb16p-46, 0x1.367ba3aaa2p-4}, - {0x1.5b873a39e56dcp-47, 0x1.471ba8a7dep-4}, - {0x1.75da8a5871b9ap-45, 0x1.4f7aad9bbcp-4}, - {0x1.ef5f3c10990f4p-45, 0x1.57e3d47c3ap-4}, - {-0x1.02359c584ac3cp-45, 0x1.68d4eaf26ep-4}, - {-0x1.41149840eaa65p-46, 0x1.715d0ce368p-4}, - {-0x1.ff281b9601ce6p-46, 0x1.79efb57b1p-4}, - {0x1.2b9da13d5c8cbp-47, 0x1.8b350364c6p-4}, - {-0x1.80743406505e6p-48, 0x1.93e7de0fc4p-4}, - {-0x1.76b169f6b4949p-49, 0x1.9ca5aa172ap-4}, - {-0x1.bc8889d0fe1ap-47, 0x1.a56e8325f6p-4}, - {-0x1.03ad4133e8c4cp-45, 0x1.b721cd1716p-4}, - {0x1.72a4e1d198491p-46, 0x1.c00c776722p-4}, - {-0x1.ddd18dedb6656p-45, 0x1.c902a19e66p-4}, - {0x1.5e533080ecf32p-47, 0x1.d204698cb4p-4}, - {0x1.7e865b8783768p-45, 0x1.db11ed766ap-4}, - {0x1.5f7ef576ada0cp-45, 0x1.ed50a4a26ep-4}, - {0x1.c9a3bd0891bccp-46, 0x1.f68216c9ccp-4}, - {-0x1.ff229f20ed3d2p-46, 0x1.ffbfc2bbc8p-4}, - {-0x1.6f30673aae7efp-45, 0x1.0484e4942bp-3}, - {0x1.dae5ed5e3f34cp-45, 0x1.093025a199p-3}, - {-0x1.3eea49e637bb3p-45, 0x1.0de1b56357p-3}, - {0x1.82c6326f70b35p-46, 0x1.1299a4fb3ep-3}, - {0x1.f04d633b79054p-45, 0x1.175805d158p-3}, - {0x1.8b891b6d05a73p-48, 0x1.1c1ce9955cp-3}, - {-0x1.35ca658049a0ap-51, 0x1.20e8624039p-3}, - {0x1.ff081a4e81f0bp-45, 0x1.25ba8215afp-3}, - {0x1.1e3f04f63ee01p-45, 0x1.2a935ba5f1p-3}, - {-0x1.e1471e5cb397ep-45, 0x1.2f7301cf4fp-3}, - {-0x1.5bd54fd6eb7d9p-45, 0x1.345987bfefp-3}, - {0x1.fe93f791a7264p-46, 0x1.394700f795p-3}, - {-0x1.8aebce3ec8738p-45, 0x1.3e3b814974p-3}, - {0x1.b0722aa2559f2p-45, 0x1.43371cde07p-3}, - {-0x1.bcb784188a058p-46, 0x1.4839e83507p-3}, - {0x1.20ca9a2bcc728p-45, 0x1.4d43f8275ap-3}, - {0x1.bb95ec8fd8f68p-45, 0x1.525561e925p-3}, - {0x1.4e036062e2e73p-48, 0x1.576e3b0bdep-3}, - {-0x1.e560b5e7a02b4p-51, 0x1.5c8e998073p-3}, - {0x1.1e472c751a4cp-49, 0x1.61b6939983p-3}, - {-0x1.1116ad28239bp-48, 0x1.66e6400da4p-3}, - {0x1.9ad1d9e405fb9p-46, 0x1.6c1db5f9bbp-3}, - {-0x1.41149840eaa65p-45, 0x1.715d0ce368p-3}, - {0x1.bfb1de334b1cbp-45, 0x1.76a45cbb7ep-3}, - {0x1.bfb1de334b1cbp-45, 0x1.76a45cbb7ep-3}, - {-0x1.9fc01708d86e7p-48, 0x1.7bf3bde09ap-3}, - {0x1.4adaf7fe992b6p-45, 0x1.814b4921bdp-3}, - {-0x1.c0b434f5d2b7ap-46, 0x1.86ab17c10cp-3}, - {0x1.4c7acd659652fp-45, 0x1.8c13437695p-3}, - {0x1.3e99da1b485cfp-45, 0x1.9183e67339p-3}, - {0x1.3e99da1b485cfp-45, 0x1.9183e67339p-3}, - {-0x1.fb7d8e74e02ap-46, 0x1.96fd1b63ap-3}, - {0x1.7c9690248757ep-46, 0x1.9c7efd734ap-3}, - {-0x1.0cee0ed4ca7e9p-52, 0x1.a209a84fbdp-3}, - {0x1.d924eb1fec6c5p-47, 0x1.a79d382bc2p-3}, - {0x1.d924eb1fec6c5p-47, 0x1.a79d382bc2p-3}, - {0x1.fe6eb5a4df1dfp-49, 0x1.ad39c9c2c6p-3}, - {0x1.4c9cce6dd603bp-46, 0x1.b2df7a5c5p-3}, - {-0x1.a01b9bb0ebf1bp-45, 0x1.b88e67cf98p-3}, - {-0x1.a01b9bb0ebf1bp-45, 0x1.b88e67cf98p-3}, - {0x1.2ee896e06dbe8p-45, 0x1.be46b08735p-3}, - {-0x1.ff2381071d23ep-49, 0x1.c4087384f5p-3}, - {-0x1.2f9fd61140aa6p-45, 0x1.c9d3d065c6p-3}, - {-0x1.2f9fd61140aa6p-45, 0x1.c9d3d065c6p-3}, - {-0x1.2386ad8b819b8p-45, 0x1.cfa8e765ccp-3}, - {0x1.d63da3ac9f0d5p-45, 0x1.d587d96494p-3}, - {0x1.d63da3ac9f0d5p-45, 0x1.d587d96494p-3}, - {0x1.fcc16f3ba09cbp-45, 0x1.db70c7e96ep-3}, - {-0x1.cc52c1ba2d838p-45, 0x1.e163d527e7p-3}, - {-0x1.cc52c1ba2d838p-45, 0x1.e163d527e7p-3}, - {0x1.f97877007c127p-46, 0x1.e76124046bp-3}, - {0x1.fbd42fdc335fdp-47, 0x1.ed68d81919p-3}, - {0x1.fbd42fdc335fdp-47, 0x1.ed68d81919p-3}, - {-0x1.cbc0789055864p-45, 0x1.f37b15bab1p-3}, - {0x1.2737df7f29668p-45, 0x1.f99801fdb7p-3}, - {0x1.2737df7f29668p-45, 0x1.f99801fdb7p-3}, - {-0x1.ff229f20ed3d2p-45, 0x1.ffbfc2bbc8p-3}, - {0x1.00809c16ae3ecp-46, 0x1.02f93f4c87p-2}, - {0x1.00809c16ae3ecp-46, 0x1.02f93f4c87p-2}, - {-0x1.aa1358e87a6b4p-45, 0x1.06182e84fd8p-2}, - {-0x1.aa1358e87a6b4p-45, 0x1.06182e84fd8p-2}, - {-0x1.f171b2c5f2274p-48, 0x1.093cc32c91p-2}, - {-0x1.42d6ae59e7d9cp-45, 0x1.0c6711d6acp-2}, - {-0x1.42d6ae59e7d9cp-45, 0x1.0c6711d6acp-2}, - {0x1.eac1871dbdbbfp-45, 0x1.0f972f87ffp-2}, - {0x1.eac1871dbdbbfp-45, 0x1.0f972f87ffp-2}, - {0x1.feed957c16a44p-46, 0x1.12cd31b9c98p-2}, - {0x1.a6023a51d15b6p-46, 0x1.16092e5d3a8p-2}, - {0x1.a6023a51d15b6p-46, 0x1.16092e5d3a8p-2}, - {0x1.cefc5208422d8p-45, 0x1.194b3bdef68p-2}, - {0x1.cefc5208422d8p-45, 0x1.194b3bdef68p-2}, - {-0x1.1d4f1e8c2daffp-55, 0x1.1c93712abc8p-2}, - {-0x1.1d4f1e8c2daffp-55, 0x1.1c93712abc8p-2}, - {0x1.40eb9b53054c3p-46, 0x1.1fe1e5af2cp-2}, - {0x1.9bbc8038401fcp-45, 0x1.2336b161b3p-2}, - {0x1.9bbc8038401fcp-45, 0x1.2336b161b3p-2}, - {0x1.09ca54daae9f9p-48, 0x1.2691ecc29fp-2}, - {0x1.09ca54daae9f9p-48, 0x1.2691ecc29fp-2}, - {0x1.2b528446968a4p-48, 0x1.29f3b0e1558p-2}, - {0x1.2b528446968a4p-48, 0x1.29f3b0e1558p-2}, - {-0x1.4548507c3dd04p-46, 0x1.2d5c1760b88p-2}, - {-0x1.4548507c3dd04p-46, 0x1.2d5c1760b88p-2}, - {-0x1.db59b99249f3ap-46, 0x1.30cb3a7bb38p-2}, - {-0x1.db59b99249f3ap-46, 0x1.30cb3a7bb38p-2}, - {0x1.fef311f12b358p-46, 0x1.34413509f78p-2}, -}; +constexpr fputil::DoubleDouble LOG10_E = {0x1.95355baaafad3p-57, + 0x1.bcb7b1526e50ep-2}; -constexpr double LOG10_R_ULP[2] = {0x1.0p-96, 0.0}; +// A simple upper bound for the error of e_x * log(2) - log(r). +constexpr double HI_ERR = 0x1.0p-85; -// Generated with Sollya: -// > P = fpminimax(log10(1 + x)/x, 6, [|D...|], [-2^-7; 2^-7], absolute); -// > dirtyinfnorm(log10(1 + x)/x - P, [-2^-7, 2^-7]); -// 0x1.9535684fb3064623001de9b13e6adf06355b5d75bp-57 -constexpr double COEFFS[7] = {0x1.bcb7b1526e50ep-2, -0x1.bcb7b1526e53fp-3, - 0x1.287a763700e4p-3, -0x1.bcb7b14641063p-4, - 0x1.63c61abdf033fp-4, -0x1.28808b8a217fcp-4, - 0x1.ffe99fc1908c6p-5}; +// Extra errors from P is from using x^2 to reduce evaluation latency. +constexpr double P_ERR = 0x1.0p-51; -constexpr double P_ERR = 0x1.0p-52; +// log10(2) with 128-bit prepcision generated by SageMath with: +// sage: (s, m, e) = RealField(128)(2).log10().sign_exponent_mantissa(); +// sage: print("MType({", hex(m % 2^64), ",", hex((m >> 64) % 2^64), "})"); +const Float128 LOG10_2(/*sign=*/false, /*exponent=*/-129, /*mantissa=*/ + MType({0x8f8959ac0b7c9178, 0x9a209a84fbcff798})); -// Number of extra range reduction steps. -constexpr size_t R_STEPS = 5; -constexpr size_t R_BITS = 4; -constexpr size_t R_SIZES = 1 << (R_BITS + 1); +// -log10(r) with 128-bit precision generated by SageMath with: +// +// for i in range(128): +// r = 2^-8 * ceil( 2^8 * (1 - 2^(-8)) / (1 + i*2^(-7)) ); +// s, m, e = RealField(128)(r).log10().sign_mantissa_exponent(); +// print("{false,", e, ", MType({", hex(m % 2^64), ",", hex((m >> 64) % 2^64), +// "})},"); +const Float128 LOG10_R1[128] = { + {false, 0, MType(0)}, + {false, -136, MType({0x65af394fe05eafd3, 0xdf3b5ebbda7e186b})}, + {false, -135, MType({0xa8fb8d87b30163b5, 0xe01d40572f029c16})}, + {false, -134, MType({0x6bb0170e5bb5d630, 0xa8c1263ac3f57eb3})}, + {false, -134, MType({0xfc2ea6eb0ea1370e, 0xe1e841bbc26204e5})}, + {false, -133, MType({0xdc8a199a4bb63382, 0x8dc2eb02274d6ff4})}, + {false, -133, MType({0x86b57ea610c7db33, 0xaacde920361dd054})}, + {false, -133, MType({0x5f034a40e6a2f09d, 0xc81618eb15421bab})}, + {false, -133, MType({0x594a31b2c5cc891c, 0xe59c7e66c5fedb4b})}, + {false, -133, MType({0x221efda58221904b, 0xf477584f97b654de})}, + {false, -132, MType({0x68a0dc47567691c9, 0x892e821975106e09})}, + {false, -132, MType({0x10bc94f44d216b49, 0x9841c66e17dfe7da})}, + {false, -132, MType({0xe303ea7e23c9d6fb, 0x9fd7be3318306cc5})}, + {false, -132, MType({0xce697dbaa00d4c7d, 0xaf1cb35bf494a8dd})}, + {false, -132, MType({0x9c216079dcf0ea96, 0xbe8380a2fa7eba5a})}, + {false, -132, MType({0x75278940eecfc3a9, 0xc643c7758283a271})}, + {false, -132, MType({0x2d3467d253e2d1fc, 0xd5de75ec27e4fe68})}, + {false, -132, MType({0xead4055dcdec7b22, 0xddb904e8f1272a95})}, + {false, -132, MType({0xe1e0dda0b3d375a4, 0xed88f6bb355fa196})}, + {false, -132, MType({0x38dc40c4fe11e608, 0xf57e8281ade9d92d})}, + {false, -131, MType({0x3bcdcfe7b23976cd, 0x82c2941bb20bbe1f})}, + {false, -131, MType({0x456350b0bda452a6, 0x86cb36632807cdcd})}, + {false, -131, MType({0x78185dcc37fda01a, 0x8eeaa306458b760a})}, + {false, -131, MType({0x307643adbbbde1b3, 0x9301839512fc1168})}, + {false, -131, MType({0x6c449d409f883fe3, 0x9b3dd1d550c41443})}, + {false, -131, MType({0x8ea7b30c8b4ad886, 0x9f6356aa03c34389})}, + {false, -131, MType({0x961c6e690d8879b4, 0xa7bd56cdde5d76a2})}, + {false, -131, MType({0x42643ced81ec14a, 0xabf1ea3e1d7bd7cf})}, + {false, -131, MType({0x4742fb3d0b5cdd19, 0xb02b9af74c2f879e})}, + {false, -131, MType({0xf7e2ab36f09e9014, 0xb8ae8671b3d7dd6c})}, + {false, -131, MType({0x8d3fc63485e7ff13, 0xbcf7dabd87c01afc})}, + {false, -131, MType({0xf3edc49375fbc5a5, 0xc1467f694d10a581})}, + {false, -131, MType({0x5fcd7d0ce937375f, 0xc9f3ef07e1f3fc5e})}, + {false, -131, MType({0x58252dada9f06111, 0xce52d50b94fa253a})}, + {false, -131, MType({0x62f01e5ff43708ab, 0xd2b74192fae43777})}, + {false, -131, MType({0x481d9b3131f52639, 0xd72142a84ca85abd})}, + {false, -131, MType({0xb305ced1419fe924, 0xdb90e68b8abf14af})}, + {false, -131, MType({0x849266a85513dc6d, 0xe48150cf32888b9c})}, + {false, -131, MType({0x80ecf3266b4dcf4, 0xe90234c65a15e533})}, + {false, -131, MType({0xe1e0dda0b3d375a4, 0xed88f6bb355fa196})}, + {false, -131, MType({0xce3537a3a211b25b, 0xf215a60b6557943f})}, + {false, -131, MType({0x5dab68307fedefcd, 0xf6a852513757dfbd})}, + {false, -131, MType({0x1be2585c279c50a5, 0xffdfe15de3c01bac})}, + {false, -130, MType({0x18aa302171017dcb, 0x8242724a155219f3})}, + {false, -130, MType({0xabc7e698502d43c0, 0x849812d0ccbb5cbd})}, + {false, -130, MType({0xc339089a51663370, 0x86f0dab1ab5822b6})}, + {false, -130, MType({0x26f70b34ce5cf201, 0x894cd27d9f182c63})}, + {false, -130, MType({0x676f20a87ab433df, 0x8bac02e8ac3e09ac})}, + {false, -130, MType({0x6db4169cc4b83bc3, 0x8e0e74caae062e24})}, + {false, -130, MType({0xcd3fdb2fad0d1fd6, 0x907431201c7f651a})}, + {false, -130, MType({0x49d03e163250d1d4, 0x92dd410ad7bfe103})}, + {false, -130, MType({0x9ec7dc02d5e723b9, 0x9549add2f8a3c7e0})}, + {false, -130, MType({0x34698d03a5442573, 0x97b980e7a743d71c})}, + {false, -130, MType({0x522904d1e47f3de, 0x9a2cc3dff7548556})}, + {false, -130, MType({0x791a72646c87b976, 0x9ca3807bca9fe93f})}, + {false, -130, MType({0x3826f190d655d736, 0x9f1dc0a4b9cea286})}, + {false, -130, MType({0x544ab3e48199b299, 0xa19b8e6f03b60e45})}, + {false, -130, MType({0xbe775fa82961114e, 0xa41cf41a83643487})}, + {false, -130, MType({0x45798e5019e6c082, 0xa6a1fc13ad241953})}, + {false, -130, MType({0x91fb1ed0cdc4d1fb, 0xa92ab0f492b772bd})}, + {false, -130, MType({0x818b8b9cbbd17b72, 0xabb71d85ef05380d})}, + {false, -130, MType({0xa50c2fea60c5b3b2, 0xae474cc0397f0d4f})}, + {false, -130, MType({0x58ea34980ad8b720, 0xb0db49ccc1823c8e})}, + {false, -130, MType({0x4b5f71941be508a4, 0xb3732006d1fbbba5})}, + {false, -130, MType({0x9e405fb8bcb1ff1e, 0xb60edafcdd99ad1d})}, + {false, -130, MType({0x9e405fb8bcb1ff1e, 0xb60edafcdd99ad1d})}, + {false, -130, MType({0xf7e2ab36f09e9014, 0xb8ae8671b3d7dd6c})}, + {false, -130, MType({0xc669639640c305bb, 0xbb522e5dbf37f63b})}, + {false, -130, MType({0xa3dc9e464e98764b, 0xbdf9def04cf980ff})}, + {false, -130, MType({0xffd3256b59fa9c59, 0xc0a5a490dea95b5e})}, + {false, -130, MType({0xb0a2d48672a051a5, 0xc3558be085e3f4bc})}, + {false, -130, MType({0xb0a2d48672a051a5, 0xc3558be085e3f4bc})}, + {false, -130, MType({0xacb2ca5d4ca1c10e, 0xc609a1bb4aa98f59})}, + {false, -130, MType({0x43690b9e3cde0d02, 0xc8c1f3399ca7d33b})}, + {false, -130, MType({0x18b1fd60383f7e5a, 0xcb7e8db1cfe04827})}, + {false, -130, MType({0x248757e5f45af3d, 0xce3f7eb9a517c969})}, + {false, -130, MType({0x7c4acd605be48bc1, 0xd104d427de7fbcc4})}, + {false, -130, MType({0x7c4acd605be48bc1, 0xd104d427de7fbcc4})}, + {false, -130, MType({0x58ff63629a92652d, 0xd3ce9c15e10ec927})}, + {false, -130, MType({0x6b49be3bd8c89f10, 0xd69ce4e16303fcdd})}, + {false, -130, MType({0xe6dd603a881e9060, 0xd96fbd2e2814c9cc})}, + {false, -130, MType({0xe6dd603a881e9060, 0xd96fbd2e2814c9cc})}, + {false, -130, MType({0x89e281c98c1d705c, 0xdc4733e7cbcbfc8c})}, + {false, -130, MType({0xdc0db7cf0cce9f32, 0xdf2358439aa5dd12})}, + {false, -130, MType({0xfdf1c5b846db9deb, 0xe20439c27a7c01b8})}, + {false, -130, MType({0xfdf1c5b846db9deb, 0xe20439c27a7c01b8})}, + {false, -130, MType({0x3dd7eab48869c402, 0xe4e9e832e2da0c05})}, + {false, -130, MType({0x4e8fcc900b41daef, 0xe7d473b2e5db8f2a})}, + {false, -130, MType({0x4e8fcc900b41daef, 0xe7d473b2e5db8f2a})}, + {false, -130, MType({0x7593e1a9e917359a, 0xeac3ecb24a3ac7b4})}, + {false, -130, MType({0xe7741396b49e1ce5, 0xedb863f4b73f982d})}, + {false, -130, MType({0xe7741396b49e1ce5, 0xedb863f4b73f982d})}, + {false, -130, MType({0xc8ba4f8f47b85a5c, 0xf0b1ea93f34675a7})}, + {false, -130, MType({0x7007c1276821b705, 0xf3b09202359f9787})}, + {false, -130, MType({0x7007c1276821b705, 0xf3b09202359f9787})}, + {false, -130, MType({0x7ee19afe6db7e324, 0xf6b46c0c8c8fdea1})}, + {false, -130, MType({0xedf54f37f6d40420, 0xf9bd8add584687f0})}, + {false, -130, MType({0xedf54f37f6d40420, 0xf9bd8add584687f0})}, + {false, -130, MType({0xefe52ccf03e7dee1, 0xfccc00fedba4e6fb})}, + {false, -130, MType({0x1be2585c279c50a5, 0xffdfe15de3c01bac})}, + {false, -130, MType({0x1be2585c279c50a5, 0xffdfe15de3c01bac})}, + {false, -129, MType({0xe0b571f5c91b0446, 0x817c9fa643880404})}, + {false, -129, MType({0x7178594bef2def59, 0x830c17427ea55eca})}, + {false, -129, MType({0x7178594bef2def59, 0x830c17427ea55eca})}, + {false, -129, MType({0x9a741bb171158d2a, 0x849e6196487c1d1c})}, + {false, -129, MType({0x9a741bb171158d2a, 0x849e6196487c1d1c})}, + {false, -129, MType({0x1a618264446cb495, 0x863388eb55ebd295})}, + {false, -129, MType({0x71dbdbbec51d7657, 0x87cb97c3ff9eac18})}, + {false, -129, MType({0x71dbdbbec51d7657, 0x87cb97c3ff9eac18})}, + {false, -129, MType({0xabe0b522230f7d14, 0x896698dce4cff76c})}, + {false, -129, MType({0xabe0b522230f7d14, 0x896698dce4cff76c})}, + {false, -129, MType({0xd28e8adafea703b4, 0x8b04972e9d4d3011})}, + {false, -129, MType({0x208422d83be34b27, 0x8ca59def7b5cefc5})}, + {false, -129, MType({0x208422d83be34b27, 0x8ca59def7b5cefc5})}, + {false, -129, MType({0xc385cf49402af0e4, 0x8e49b8955e3ffb8a})}, + {false, -129, MType({0xc385cf49402af0e4, 0x8e49b8955e3ffb8a})}, + {false, -129, MType({0xda982a614e12c6dd, 0x8ff0f2d7960a075c})}, + {false, -129, MType({0xda982a614e12c6dd, 0x8ff0f2d7960a075c})}, + {false, -129, MType({0x38401fc1c1b5c2c, 0x919b58b0d999bbc8})}, + {false, -129, MType({0x38401fc1c1b5c2c, 0x919b58b0d999bbc8})}, + {false, -129, MType({0xa9b55d3f16da746a, 0x9348f6614f821394})}, + {false, -129, MType({0xa9b55d3f16da746a, 0x9348f6614f821394})}, + {false, -129, MType({0x88d2d1473d4f7f5, 0x94f9d870aac256a5})}, + {false, -129, MType({0x88d2d1473d4f7f5, 0x94f9d870aac256a5})}, + {false, -129, MType({0x7c1e117dea19e9e6, 0x96ae0bb05c35d5bd})}, + {false, -129, MType({0x7c1e117dea19e9e6, 0x96ae0bb05c35d5bd})}, + {false, -129, MType({0x336db0630f536fb9, 0x98659d3dd9b12532})}, + {false, 0, MType(0)}, +}; -// Generated by Sollya with: -// for i from 0 to 4 do { -// N = 11 + 4*i; -// print ("{"); -// for j from -2^4 to 2^4 - 1 do { -// r = 2^(-N) * nearestint(2^(N) * ( 1 + (j + 0.5)*2^(-N) - 2^(-2*N-1)) / -// ((1 + j * 2^(-N)) * (1 + (j + 1)*2^(-N)))); -// print(r, ","); -// }; -// print("},"); -// }; -constexpr double RR[R_STEPS][R_SIZES] = { - { - 0x1.02p0, 0x1.01ep0, 0x1.01cp0, 0x1.01ap0, 0x1.018p0, 0x1.016p0, - 0x1.014p0, 0x1.012p0, 0x1.01p0, 0x1.00ep0, 0x1.00cp0, 0x1.00ap0, - 0x1.008p0, 0x1.006p0, 0x1.004p0, 0x1p0, 0x1p0, 0x1.ffcp-1, - 0x1.ff8p-1, 0x1.ff4p-1, 0x1.ffp-1, 0x1.fecp-1, 0x1.fe8p-1, 0x1.fe4p-1, - 0x1.fep-1, 0x1.fdcp-1, 0x1.fd8p-1, 0x1.fd4p-1, 0x1.fdp-1, 0x1.fccp-1, - 0x1.fc8p-1, 0x1.fc4p-1, - }, - { - 0x1.002p0, 0x1.001ep0, 0x1.001cp0, 0x1.001ap0, 0x1.0018p0, - 0x1.0016p0, 0x1.0014p0, 0x1.0012p0, 0x1.001p0, 0x1.000ep0, - 0x1.000cp0, 0x1.000ap0, 0x1.0008p0, 0x1.0006p0, 0x1.0004p0, - 0x1p0, 0x1p0, 0x1.fffcp-1, 0x1.fff8p-1, 0x1.fff4p-1, - 0x1.fffp-1, 0x1.ffecp-1, 0x1.ffe8p-1, 0x1.ffe4p-1, 0x1.ffep-1, - 0x1.ffdcp-1, 0x1.ffd8p-1, 0x1.ffd4p-1, 0x1.ffdp-1, 0x1.ffccp-1, - 0x1.ffc8p-1, 0x1.ffc4p-1, - }, - { - 0x1.0002p0, 0x1.0001ep0, 0x1.0001cp0, 0x1.0001ap0, 0x1.00018p0, - 0x1.00016p0, 0x1.00014p0, 0x1.00012p0, 0x1.0001p0, 0x1.0000ep0, - 0x1.0000cp0, 0x1.0000ap0, 0x1.00008p0, 0x1.00006p0, 0x1.00004p0, - 0x1p0, 0x1p0, 0x1.ffffcp-1, 0x1.ffff8p-1, 0x1.ffff4p-1, - 0x1.ffffp-1, 0x1.fffecp-1, 0x1.fffe8p-1, 0x1.fffe4p-1, 0x1.fffep-1, - 0x1.fffdcp-1, 0x1.fffd8p-1, 0x1.fffd4p-1, 0x1.fffdp-1, 0x1.fffccp-1, - 0x1.fffc8p-1, 0x1.fffc4p-1, - }, - { - 0x1.00002p0, 0x1.00001ep0, 0x1.00001cp0, 0x1.00001ap0, - 0x1.000018p0, 0x1.000016p0, 0x1.000014p0, 0x1.000012p0, - 0x1.00001p0, 0x1.00000ep0, 0x1.00000cp0, 0x1.00000ap0, - 0x1.000008p0, 0x1.000006p0, 0x1.000004p0, 0x1p0, - 0x1p0, 0x1.fffffcp-1, 0x1.fffff8p-1, 0x1.fffff4p-1, - 0x1.fffffp-1, 0x1.ffffecp-1, 0x1.ffffe8p-1, 0x1.ffffe4p-1, - 0x1.ffffep-1, 0x1.ffffdcp-1, 0x1.ffffd8p-1, 0x1.ffffd4p-1, - 0x1.ffffdp-1, 0x1.ffffccp-1, 0x1.ffffc8p-1, 0x1.ffffc4p-1, - }, - { - 0x1.000002p0, 0x1.000001ep0, 0x1.000001cp0, 0x1.000001ap0, - 0x1.0000018p0, 0x1.0000016p0, 0x1.0000014p0, 0x1.0000012p0, - 0x1.000001p0, 0x1.000000ep0, 0x1.000000cp0, 0x1.000000ap0, - 0x1.0000008p0, 0x1.0000006p0, 0x1.0000004p0, 0x1p0, - 0x1p0, 0x1.ffffffcp-1, 0x1.ffffff8p-1, 0x1.ffffff4p-1, - 0x1.ffffffp-1, 0x1.fffffecp-1, 0x1.fffffe8p-1, 0x1.fffffe4p-1, - 0x1.fffffep-1, 0x1.fffffdcp-1, 0x1.fffffd8p-1, 0x1.fffffd4p-1, - 0x1.fffffdp-1, 0x1.fffffccp-1, 0x1.fffffc8p-1, 0x1.fffffc4p-1, - }, +// Range reduction - Step 2: +// r(k) = 2^-16 round(2^16 / (1 + k*2^-14)) for k = -2^6 .. 2^7. +// Output range: +// [-0x1.3ffcp-15, 0x1.3e3dp-15] + +// We store S2[i] = 2^16 (r(i - 2^6) - 1). +constexpr int64_t S2[193] = { + 0x101, 0xfd, 0xf9, 0xf5, 0xf1, 0xed, 0xe9, 0xe5, 0xe1, + 0xdd, 0xd9, 0xd5, 0xd1, 0xcd, 0xc9, 0xc5, 0xc1, 0xbd, + 0xb9, 0xb4, 0xb0, 0xac, 0xa8, 0xa4, 0xa0, 0x9c, 0x98, + 0x94, 0x90, 0x8c, 0x88, 0x84, 0x80, 0x7c, 0x78, 0x74, + 0x70, 0x6c, 0x68, 0x64, 0x60, 0x5c, 0x58, 0x54, 0x50, + 0x4c, 0x48, 0x44, 0x40, 0x3c, 0x38, 0x34, 0x30, 0x2c, + 0x28, 0x24, 0x20, 0x1c, 0x18, 0x14, 0x10, 0xc, 0x8, + 0x4, 0x0, -0x4, -0x8, -0xc, -0x10, -0x14, -0x18, -0x1c, + -0x20, -0x24, -0x28, -0x2c, -0x30, -0x34, -0x38, -0x3c, -0x40, + -0x44, -0x48, -0x4c, -0x50, -0x54, -0x58, -0x5c, -0x60, -0x64, + -0x68, -0x6c, -0x70, -0x74, -0x78, -0x7c, -0x80, -0x84, -0x88, + -0x8c, -0x90, -0x94, -0x98, -0x9c, -0xa0, -0xa4, -0xa8, -0xac, + -0xb0, -0xb4, -0xb7, -0xbb, -0xbf, -0xc3, -0xc7, -0xcb, -0xcf, + -0xd3, -0xd7, -0xdb, -0xdf, -0xe3, -0xe7, -0xeb, -0xef, -0xf3, + -0xf7, -0xfb, -0xff, -0x103, -0x107, -0x10b, -0x10f, -0x113, -0x117, + -0x11b, -0x11f, -0x123, -0x127, -0x12b, -0x12f, -0x133, -0x137, -0x13a, + -0x13e, -0x142, -0x146, -0x14a, -0x14e, -0x152, -0x156, -0x15a, -0x15e, + -0x162, -0x166, -0x16a, -0x16e, -0x172, -0x176, -0x17a, -0x17e, -0x182, + -0x186, -0x18a, -0x18e, -0x192, -0x195, -0x199, -0x19d, -0x1a1, -0x1a5, + -0x1a9, -0x1ad, -0x1b1, -0x1b5, -0x1b9, -0x1bd, -0x1c1, -0x1c5, -0x1c9, + -0x1cd, -0x1d1, -0x1d5, -0x1d9, -0x1dd, -0x1e0, -0x1e4, -0x1e8, -0x1ec, + -0x1f0, -0x1f4, -0x1f8, -0x1fc}; + +// -log10(r) for the second step, generated by SageMath with: +// +// for i in range(-2^6, 2^7 + 1): +// r = 2^-16 * round( 2^16 / (1 + i*2^(-14)) ); +// s, m, e = RealField(128)(r).log10().sign_mantissa_exponent(); +// print("{false," if s == -1 else "{true,", e, ", +// MType({", hex(m % 2^64), ",", hex((m >> 64) % 2^64), "})},"); +const Float128 LOG10_R2[193] = { + {true, -137, MType({0x7f1ce002fa34131b, 0xdeca729013cd7c31})}, + {true, -137, MType({0x639afa085dd8b4c7, 0xdb5475b44946d986})}, + {true, -137, MType({0x5512632fe9a58cb, 0xd7de6b0e10cab7d2})}, + {true, -137, MType({0xb5380a9953117d07, 0xd468529cfc6fb395})}, + {true, -137, MType({0x70af2d7d53be1f31, 0xd0f22c609e474741})}, + {true, -137, MType({0xccd499c49b74cc2, 0xcd7bf858885dcae2})}, + {true, -137, MType({0x5b51ddc3987ebfb8, 0xca05b6844cba73cf})}, + {true, -137, MType({0x49375f5189b3782b, 0xc68f66e37d5f545a})}, + {true, -137, MType({0xf6e57738865c712f, 0xc3190975ac495b7a})}, + {true, -137, MType({0xca02b10a8c712acd, 0xbfa29e3a6b70547e})}, + {true, -137, MType({0x78e5038210208151, 0xbc2c25314cc6e6b6})}, + {true, -137, MType({0xfa099ecd71ee0ea, 0xb8b59e59e23a9524})}, + {true, -137, MType({0xeeb445ccb8fb09ed, 0xb53f09b3bdb3be28})}, + {true, -137, MType({0xc352fff18a1c02fb, 0xb1c8673e71159b33})}, + {true, -137, MType({0x7949e03ecf9b390b, 0xae51b6f98e3e406e})}, + {true, -137, MType({0x2681f33f30aadedc, 0xaadaf8e4a7069c6c})}, + {true, -137, MType({0xf01d5496eea213b3, 0xa7642cff4d4277d6})}, + {true, -137, MType({0xe92ef555ff1de975, 0xa3ed534912c0751d})}, + {true, -137, MType({0xeb0c7519b3e7c1e0, 0xa0766bc1894a1022})}, + {true, -137, MType({0xf60d204ff0fe5296, 0x9c21b6e91e7f03a3})}, + {true, -137, MType({0x125c19a4f057c18b, 0x98aab0491050bea8})}, + {true, -137, MType({0x7e9383ce1bdf9575, 0x95339bd64cd953e7})}, + {true, -137, MType({0xbf274f4d8f770253, 0x91bc799065cc57d6})}, + {true, -137, MType({0x656bd9b758fe44ba, 0x8e454976ecd836ad})}, + {true, -137, MType({0xbfdd2c7f388fc014, 0x8ace0b8973a63413})}, + {true, -137, MType({0x83fbf6ed936c493a, 0x8756bfc78bda6ad0})}, + {true, -137, MType({0x71bfa9a18bec01cc, 0x83df6630c713cc76})}, + {true, -137, MType({0xf09d19f56dbfef72, 0x8067fec4b6ec2111})}, + {true, -138, MType({0x4c422713b1642228, 0xf9e11305d9f00dad})}, + {true, -138, MType({0xc3c7c5699b7a0a4, 0xf2f20cd5f58de39a})}, + {true, -138, MType({0xb8db7c69e3fa0797, 0xec02eaf8e3c656ff})}, + {true, -138, MType({0xa083eb05506ff7ed, 0xe513ad6dc7a3a553})}, + {true, -138, MType({0xc21595e745f1fa15, 0xde245433c425b5c5})}, + {true, -138, MType({0xb9d5bcdbfe719389, 0xd734df49fc42189b})}, + {true, -138, MType({0xa17a1e85e93461f4, 0xd0454eaf92e4068b})}, + {true, -138, MType({0xe3537584da333fda, 0xc955a263aaec6016})}, + {true, -138, MType({0x963177f24682c2, 0xc265da656731ace5})}, + {true, -138, MType({0x4ac037347bcfc50e, 0xbb75f6b3ea801b1e})}, + {true, -138, MType({0x901a736a4364cdfd, 0xb485f74e57997ec6})}, + {true, -138, MType({0xbb550acc3b9d7247, 0xad95dc33d1355117})}, + {true, -138, MType({0x663cf2b27e8f1ffb, 0xa6a5a5637a00afdc})}, + {true, -138, MType({0x5f89bd08feb39952, 0x9fb552dc749e5cca})}, + {true, -138, MType({0x23c2623c73f494db, 0x98c4e49de3a6bcdd})}, + {true, -138, MType({0x4937d3b5485af61e, 0x91d45aa6e9a7d7b0})}, + {true, -138, MType({0xdf14214e7a6d8111, 0x8ae3b4f6a92556d9})}, + {true, -138, MType({0xbf7cfc14999fb4bc, 0x83f2f38c44988544})}, + {true, -139, MType({0xa990c0ee569a8d51, 0xfa042ccdbce09d15})}, + {true, -139, MType({0xa38463e9d941e1c2, 0xec223b0b32227c9e})}, + {true, -139, MType({0xba0324530edaa03f, 0xde4011cf2daaff31})}, + {true, -139, MType({0x5e997a02dad7ace7, 0xd05db117f419b857})}, + {true, -139, MType({0x4a14676d4d0f817e, 0xc27b18e3c9f977c7})}, + {true, -139, MType({0x857c002ee7a1e473, 0xb4984930f3c0481c})}, + {true, -139, MType({0x5923b2eb72d8012a, 0xa6b541fdb5cf6d89})}, + {true, -139, MType({0x21cde8f85ca1f9fd, 0x98d203485473648b})}, + {true, -139, MType({0xbe08e08b1d212d4, 0x8aee8d0f13e3e09e})}, + {true, -140, MType({0x695023998e6bd7b0, 0xfa15bea0708795e1})}, + {true, -140, MType({0x634cea6750617a92, 0xde4df4140b42822f})}, + {true, -140, MType({0xfbd7e970aef9dbb8, 0xc285ba757feb2781})}, + {true, -140, MType({0x9aedc1c1ba7d0695, 0xa6bd11c1564a8ace})}, + {true, -140, MType({0x8d306ba207233c44, 0x8af3f9f41600120a})}, + {true, -141, MType({0x856a0a3a00fcf3c1, 0xde54e6148d030322})}, + {true, -141, MType({0xb3a2c1407cf6d38d, 0xa6c0fa00de35f314})}, + {true, -142, MType({0xd791cf6a70c3a504, 0xde585f4c5bbbcd3d})}, + {true, -143, MType({0x10a633f2c4a8ea22, 0xde5a1bf627b1f68f})}, + {true, 0, MType({0x0, 0x0})}, + {false, -143, MType({0xed4a68e5e6e83ddf, 0xde5d95658a729eab})}, + {false, -142, MType({0x3281f1872cdbee94, 0xde5f522b21e3e25a})}, + {false, -141, MType({0xf1466edaa96e356e, 0xa6c8cb3b7e5bbbfd})}, + {false, -141, MType({0x8a607fd695dfc3d9, 0xde62cbd21e895473})}, + {false, -140, MType({0xc36b8713ceefe2de, 0x8afed57032bebc7c})}, + {false, -140, MType({0x5c2e76c953e3e3e6, 0xa6ccb436a3c72fa4})}, + {false, -140, MType({0x8e4950fa5c943bbf, 0xc29b023fdcb2dccf})}, + {false, -140, MType({0x20fa8a73c585f634, 0xde69bf8f58005dfc})}, + {false, -140, MType({0xaa106d9b0a9717a, 0xfa38ec28905810a3})}, + {false, -139, MType({0x85d70e032de41aec, 0x8b04440780460c2a})}, + {false, -139, MType({0xbeee21cbb82a9a78, 0x98ec49a311cc30ab})}, + {false, -139, MType({0xabd7b0fdd8efe6f6, 0xa6d486e8ba5151a0})}, + {false, -139, MType({0x3221c56e2c1aa912, 0xb4bcfbda377d31cc})}, + {false, -139, MType({0x57b795a36d9c5f19, 0xc2a5a879470c7c37})}, + {false, -139, MType({0x131ec142c053ac3b, 0xd08e8cc7a6d0c580})}, + {false, -139, MType({0x35e3298f4bb2aa0a, 0xde77a8c714b08d28})}, + {false, -139, MType({0x7133dafdfc44f160, 0xec60fc794ea73ee4})}, + {false, -139, MType({0x74b37d23121c59d5, 0xfa4a87e012c533eb})}, + {false, -138, MType({0x93bf5f4207da8a4c, 0x841a257e8f97da22})}, + {false, -138, MType({0xfdb5990ec6057f4e, 0x8b0f22e919107c0c})}, + {false, -138, MType({0x2d408a58b1b202fe, 0x92043c3084f41481})}, + {false, -138, MType({0x1759381b61dfbf01, 0x98f97155b274b1ab})}, + {false, -138, MType({0x41e90a054df4b9f1, 0x9feec25980cedbbe})}, + {false, -138, MType({0xa1e66c6203725d50, 0xa6e42f3ccf49959d})}, + {false, -138, MType({0x8693d36ab45bd7ce, 0xadd9b8007d365d83})}, + {false, -138, MType({0x91e25bb40ad3f098, 0xb4cf5ca569f12da9})}, + {false, -138, MType({0xbdf94392c4cc7f6c, 0xbbc51d2c74e07cf0})}, + {false, -138, MType({0x6fe37973354a82f9, 0xc2baf9967d753f89})}, + {false, -138, MType({0x97647b4267bfd801, 0xc9b0f1e4632ae79b})}, + {false, -138, MType({0xdbf5c32a454f7bdf, 0xd0a70617058765ee})}, + {false, -138, MType({0xd6edfe04c37ba916, 0xd79d362f441b2a92})}, + {false, -138, MType({0x5ad3480ccfbe9890, 0xde93822dfe812587})}, + {false, -138, MType({0xc7d9ac765be7e325, 0xe589ea14145ec764})}, + {false, -138, MType({0x6d8f24b9a3ca011b, 0xec806de265640204})}, + {false, -138, MType({0xf9b654807dcdd5b2, 0xf3770d99d14b4928})}, + {false, -138, MType({0xf4513f4745663028, 0xfa6dc93b37d99326})}, + {false, -137, MType({0xa46e9a72d80da75f, 0x80b25063bc6f2cc6})}, + {false, -137, MType({0xee60992b51ffac4b, 0x842dca1fba19cce6})}, + {false, -137, MType({0x1977fa1c786886b3, 0x87a951d204deeaf3})}, + {false, -137, MType({0xe5f7c52cdf119d5, 0x8b24e77b0cb60a84})}, + {false, -137, MType({0x3bf9d70da1021a10, 0x8ea08b1b419bf221})}, + {false, -137, MType({0xfd0406b07523b8e6, 0x921c3cb31392ab94})}, + {false, -137, MType({0x453ee32c020f2a8, 0x9597fc42f2a18441})}, + {false, -137, MType({0xcfb3ec22066bf7f6, 0x9913c9cb4ed50d72})}, + {false, -137, MType({0x215c025bd493ecf9, 0x9c8fa54c983f1cb8})}, + {false, -137, MType({0x39c116b7ee3a83ec, 0x9f2c93192e68232b})}, + {false, -137, MType({0xf41f4b3ede2782f0, 0xa2a8870f24ac5f66})}, + {false, -137, MType({0x61196927723eb75c, 0xa62488ff3c735799})}, + {false, -137, MType({0xe615e836cb1edab, 0xa9a098e9e5e2a432})}, + {false, -137, MType({0x6981331c5fc71cfc, 0xad1cb6cf91252372})}, + {false, -137, MType({0x5f6a4faa054f11fa, 0xb098e2b0ae6af9c2})}, + {false, -137, MType({0x2a68bc681a74c28, 0xb4151c8dade99205})}, + {false, -137, MType({0x382ba24d90566403, 0xb7916466ffdb9ded})}, + {false, -137, MType({0x6ad1abe51dd22e00, 0xbb0dba3d14811652})}, + {false, -137, MType({0x456d3f7f59b13960, 0xbe8a1e105c1f3b85})}, + {false, -137, MType({0x738dd8b7d66e9058, 0xc2068fe1470095a4})}, + {false, -137, MType({0x68e123fed7ff11c6, 0xc5830fb04574f4f1})}, + {false, -137, MType({0x2f3bd09780c3aa11, 0xc8ff9d7dc7d17225})}, + {false, -137, MType({0x3b48887f1ce36935, 0xcc7c394a3e706ec5})}, + {false, -137, MType({0x47ddae655ecc4633, 0xcff8e31619b19578})}, + {false, -137, MType({0x37fa81eef4819c88, 0xd3759ae1c9f9da5b})}, + {false, -137, MType({0xff6c4a8d747c65ed, 0xd6f260adbfb37b55})}, + {false, -137, MType({0x921c29493a33318c, 0xda6f347a6b4e0070})}, + {false, -137, MType({0xda0631eb65e731d8, 0xddec16483d3e3c27})}, + {false, -137, MType({0xb3da6c07d110babc, 0xe1690617a5fe4bc2})}, + {false, -137, MType({0xf2485c7868b8835a, 0xe4e603e9160d97a6})}, + {false, -137, MType({0x67f5b7ed01344055, 0xe8630fbcfdf0d3ae})}, + {false, -137, MType({0xf820df445b1d0622, 0xebe02993ce31ff7b})}, + {false, -137, MType({0xadefc674b7eca5cd, 0xef5d516df76066d0})}, + {false, -137, MType({0xda6be6dc057d3235, 0xf2da874bea10a1e0})}, + {false, -137, MType({0x392bdde152ab5ff5, 0xf657cb2e16dc95a9})}, + {false, -137, MType({0x1bab58e2ec99cf73, 0xf9d51d14ee637444})}, + {false, -137, MType({0x9b51ef7e3388d692, 0xfd527d00e149bd3e})}, + {false, -136, MType({0xe914c6a7f3f22fa2, 0x8067f579301c9ef6})}, + {false, -136, MType({0xd22862eb2081c94, 0x8226b374edf088e2})}, + {false, -136, MType({0x29ebd0b476cd8fd8, 0x83e57873e27ad153})}, + {false, -136, MType({0x98feddc2806d01ed, 0x85a44476461854a0})}, + {false, -136, MType({0x471bfc261a401854, 0x8763177c512896af})}, + {false, -136, MType({0xb6f89c19b4cd1acd, 0x88b23a5b61430a16})}, + {false, -136, MType({0xb39aaf34163fb099, 0x8a7119a85909ebe9})}, + {false, -136, MType({0x1665f0f821541c36, 0x8c2ffff99357e887})}, + {false, -136, MType({0xa5051754e049c1cb, 0x8deeed4f489679a6})}, + {false, -136, MType({0x8c5a9a1c57b2e986, 0x8fade1a9b131c159})}, + {false, -136, MType({0x1d8448438a26a9ae, 0x916cdd0905988a35})}, + {false, -136, MType({0x8e3a0913ecd2fd02, 0x932bdf6d7e3c477d})}, + {false, -136, MType({0xbc881a45f47f1d36, 0x94eae8d753911550})}, + {false, -136, MType({0xf5e51c05499b06d0, 0x96a9f946be0db8d0})}, + {false, -136, MType({0xc1a43be81a243fde, 0x986910bbf62ba04f})}, + {false, -136, MType({0xaec3cfebe971beb7, 0x9a282f373466e378})}, + {false, -136, MType({0x2518b29328614989, 0x9be754b8b13e437c})}, + {false, -136, MType({0x39d6b147cbe803a4, 0x9da68140a5332b3a})}, + {false, -136, MType({0x87765e3004ae428d, 0x9f65b4cf48c9af6d})}, + {false, -136, MType({0x8f896ab28245bac, 0xa124ef64d4888ed6})}, + {false, -136, MType({0xf8880fb5ca630c87, 0xa2e4310180f93263})}, + {false, -136, MType({0xb179397cf82e935c, 0xa4a379a586a7ad62})}, + {false, -136, MType({0x95a8cb717197ad81, 0xa662c9511e22bda3})}, + {false, -136, MType({0xf6394a34b7f9a4a4, 0xa82220047ffbcba8})}, + {false, -136, MType({0xffafd8c2b57884e8, 0xa9e17dbfe4c6ead0})}, + {false, -136, MType({0xa970a643b8a6ac2b, 0xaba0e283851ad980})}, + {false, -136, MType({0xa89b49fb749d47e0, 0xad604e4f9991014e})}, + {false, -136, MType({0x66475ed2ac983305, 0xaf1fc1245ac5772e})}, + {false, -136, MType({0xb4fd6209364bb36f, 0xb06f5be1bf1918e7})}, + {false, -136, MType({0x8b5ce79b0965962a, 0xb22edb0636da31d6})}, + {false, -136, MType({0x6724232b07396427, 0xb3ee6133f7149769})}, + {false, -136, MType({0x2f02b14dcad8a49c, 0xb5adee6b386e62ae})}, + {false, -136, MType({0xbd6443a81f792e07, 0xb76d82ac339058db})}, + {false, -136, MType({0xea1cd9625749939a, 0xb92d1df72125eb7c})}, + {false, -136, MType({0x97775e3142198913, 0xbaecc04c39dd389b})}, + {false, -136, MType({0xc2a701b809a2bc39, 0xbcac69abb6670aeb})}, + {false, -136, MType({0x979b990f39e662e3, 0xbe6c1a15cf76d9f6})}, + {false, -136, MType({0x88395c463ddd82b2, 0xc02bd18abdc2ca45})}, + {false, -136, MType({0x66f451bd9ba5ed05, 0xc1eb900aba03ad8d})}, + {false, -136, MType({0x84cfb9413f6437a6, 0xc3ab5595fcf502d9})}, + {false, -136, MType({0xd2c1c8d32943ca42, 0xc56b222cbf54f6b6})}, + {false, -136, MType({0x67c0d1fd95192e6, 0xc72af5cf39e4635f})}, + {false, -136, MType({0xc298bf9edb6441f2, 0xc8ead07da566d0e3})}, + {false, -136, MType({0xc22d646addde3910, 0xcaaab2383aa27559})}, + {false, -136, MType({0x7c301e5c7d1ca40, 0xcc6a9aff32603504})}, + {false, -136, MType({0xfb444464df02505, 0xce2a8ad2c56ba27f})}, + {false, -136, MType({0x5f1df3591ae898f, 0xcfea81b32c92feec})}, + {false, -136, MType({0xb43caf8e7b891066, 0xd13a7f7c07506f7d})}, + {false, -136, MType({0x597fb13f0d0fdf19, 0xd2fa82b36a610c4f})}, + {false, -136, MType({0x3c21f1c60a60b0d6, 0xd4ba8cf83dd2a06b})}, + {false, -136, MType({0x2b7455909a0428a4, 0xd67a9e4aba7d7ce5})}, + {false, -136, MType({0x1438b60573d2da10, 0xd83ab6ab193ca223})}, + {false, -136, MType({0x49f86400c5ab2b11, 0xd9fad61992edc008})}, + {false, -136, MType({0xd3c313d148a23c35, 0xdbbafc9660713620})}, + {false, -136, MType({0xbc56852355e0f0d5, 0xdd7b2a21baaa13cc})}, }; -// log10(2) with 192-bit prepcision generated by SageMath with: -// sage: (s, m, e) = RealField(192)(2).log10().sign_exponent_mantissa(); -// sage: print("MType({", hex(m % 2^64), ",", hex((m >> 64) % 2^64), ",", -// hex((m >> 128) % 2^64), "})"); -const Float192 LOG10_2(/*sign=*/false, /*exponent=*/-193, /*mantissa=*/ - MType({0x26ad30c543d1f34a, 0x8f8959ac0b7c9178, - 0x9a209a84fbcff798})); +// Range reduction - Step 3: +// r(k) = 2^-21 round(2^21 / (1 + k*2^-21)) for k = -80 .. 80. +// Output range: +// [-0x1.01928p-22 , 0x1p-22] + +// We store S[i] = 2^21 (r(i - 80) - 1). +constexpr int64_t S3[161] = { + 0x50, 0x4f, 0x4e, 0x4d, 0x4c, 0x4b, 0x4a, 0x49, 0x48, 0x47, 0x46, + 0x45, 0x44, 0x43, 0x42, 0x41, 0x40, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, + 0x3a, 0x39, 0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, + 0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25, + 0x24, 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, + 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0xf, + 0xe, 0xd, 0xc, 0xb, 0xa, 0x9, 0x8, 0x7, 0x6, 0x5, 0x4, + 0x3, 0x2, 0x1, 0x0, -0x1, -0x2, -0x3, -0x4, -0x5, -0x6, -0x7, + -0x8, -0x9, -0xa, -0xb, -0xc, -0xd, -0xe, -0xf, -0x10, -0x11, -0x12, + -0x13, -0x14, -0x15, -0x16, -0x17, -0x18, -0x19, -0x1a, -0x1b, -0x1c, -0x1d, + -0x1e, -0x1f, -0x20, -0x21, -0x22, -0x23, -0x24, -0x25, -0x26, -0x27, -0x28, + -0x29, -0x2a, -0x2b, -0x2c, -0x2d, -0x2e, -0x2f, -0x30, -0x31, -0x32, -0x33, + -0x34, -0x35, -0x36, -0x37, -0x38, -0x39, -0x3a, -0x3b, -0x3c, -0x3d, -0x3e, + -0x3f, -0x40, -0x41, -0x42, -0x43, -0x44, -0x45, -0x46, -0x47, -0x48, -0x49, + -0x4a, -0x4b, -0x4c, -0x4d, -0x4e, -0x4f, -0x50, +}; -// -log10(r) with 192-bit precision generated by SageMath with: +// -log10(r) for the third step, generated by SageMath with: // -// for i in range(128): -// r = 2^-8 * round( 2^8 * (1 + (i + 1/2)*2^(-7) - 2^(-15)) / ((1 + i*2^-7)*(1 -// + (i + 1)*2^-7)) ); s, m, e = RR(r).log10().sign_mantissa_exponent(); -// print("{false,", e, ", MType({", hex(m % 2^64), ",", hex((m >> 64) % 2^64), -// ",", hex((m >> 128) % 2^64), "})},"); -const Float192 LOG10_R_F192[128] = { - {false, 0, MType(0)}, - {false, -199, - MType({0x3b7bb8a51a78c8bd, 0x6e321c6a7cdecc4, 0xa7c10291a88164ae})}, - {false, -198, - MType({0xf4ba30d77042aac0, 0xa8cb8a86f6040a23, 0x8c596e4695dc8721})}, - {false, -198, - MType({0x49fd078256b3ba8b, 0xeb19e4156cfa1bb7, 0xc546035d8e97a03e})}, - {false, -198, - MType({0x3d964e8c5b12cf00, 0xb6e6ed36c9800088, 0xfea81e1c8278eafa})}, - {false, -197, - MType({0x9c97a4a794669437, 0x714446c4f6a91d15, 0x9c40d3dc0c7cf2f6})}, - {false, -197, - MType({0x1fc57458d58421ab, 0x86b57ea610c7db33, 0xaacde920361dd054})}, - {false, -197, - MType({0x89be5385cc62fb89, 0x5f034a40e6a2f09c, 0xc81618eb15421bab})}, - {false, -197, - MType({0x8b3be744561e443e, 0x594a31b2c5cc891b, 0xe59c7e66c5fedb4b})}, - {false, -196, - MType({0xb1afe1d0add7d035, 0x69b7270237094316, 0x81b1120f31c762fb})}, - {false, -196, - MType({0x6821aa1f743fb5b9, 0x68a0dc47567691c9, 0x892e821975106e09})}, - {false, -196, - MType({0x1935f7436a3ea32c, 0x10bc94f44d216b49, 0x9841c66e17dfe7da})}, - {false, -196, - MType({0x3dfba019afa885f9, 0xe74da327d8d80cb, 0xa77607122c797fcd})}, - {false, -196, - MType({0x7d002c9ce2b6dff3, 0xce697dbaa00d4c7d, 0xaf1cb35bf494a8dd})}, - {false, -196, - MType({0x9ff137c69b2cf640, 0x9c216079dcf0ea95, 0xbe8380a2fa7eba5a})}, - {false, -196, - MType({0x94d5d9c17fa207c5, 0xf5b91598205b8144, 0xce0cbd5f806eb73c})}, - {false, -196, - MType({0x8f995b90cbedc22d, 0x2d3467d253e2d1fb, 0xd5de75ec27e4fe68})}, - {false, -196, - MType({0x8b3be744561e443e, 0x594a31b2c5cc891b, 0xe59c7e66c5fedb4b})}, - {false, -196, - MType({0x97079feab7423d9b, 0xe1e0dda0b3d375a3, 0xed88f6bb355fa196})}, - {false, -196, - MType({0xe86f834386695343, 0x7b98e7f593daf19e, 0xfd7d369cbf7ed8b1})}, - {false, -195, - MType({0x5d4cae75ae8c48e7, 0x3bcdcfe7b23976cd, 0x82c2941bb20bbe1f})}, - {false, -195, - MType({0x67047204db2989f7, 0xb9a7901be7521304, 0x8ad88d04a50d4d2b})}, - {false, -195, - MType({0x829acbf3088a2849, 0x78185dcc37fda019, 0x8eeaa306458b760a})}, - {false, -195, - MType({0x9d5d4ea0a7c8afb1, 0x1581a26448e2ac0e, 0x971d3a05bc0074a2})}, - {false, -195, - MType({0xa078ffeb008a04d8, 0x6c449d409f883fe2, 0x9b3dd1d550c41443})}, - {false, -195, - MType({0x2ede0aa760148d65, 0xa39e56dbb661c829, 0xa38dd453ef15b873})}, - {false, -195, - MType({0x1716e6f9b3225217, 0x961c6e690d8879b4, 0xa7bd56cdde5d76a2})}, - {false, -195, - MType({0x5bcb3818decefa22, 0x42643ced81ec14a, 0xabf1ea3e1d7bd7cf})}, - {false, -195, - MType({0x164c684a1951204a, 0xe9ed4f101c5ef101, 0xb46a757936bf7298})}, - {false, -195, - MType({0xcff88d82b3417f9b, 0xf7e2ab36f09e9013, 0xb8ae8671b3d7dd6c})}, - {false, -195, - MType({0x8a86f0b2dfd799c2, 0x8d3fc63485e7ff12, 0xbcf7dabd87c01afc})}, - {false, -195, - MType({0xf0e9563d52c1d533, 0x13d5c8cb231a53bd, 0xc59a81b26312b9da})}, - {false, -195, - MType({0xa004d184e2faf2ea, 0x5fcd7d0ce937375e, 0xc9f3ef07e1f3fc5e})}, - {false, -195, - MType({0x8a03e643ccfc8ec7, 0x58252dada9f06110, 0xce52d50b94fa253a})}, - {false, -195, - MType({0xed0ad59454d36575, 0x62f01e5ff43708aa, 0xd2b74192fae43777})}, - {false, -195, - MType({0x3af155936af69c0b, 0xb305ced1419fe924, 0xdb90e68b8abf14af})}, - {false, -195, - MType({0x77f157444abbe2fc, 0x3a330921681e2481, 0xe0063bb3912e549c})}, - {false, -195, - MType({0x693eca0a0148cc18, 0x849266a85513dc6d, 0xe48150cf32888b9c})}, - {false, -195, - MType({0x73dac2c5ab4c8eda, 0x80ecf3266b4dcf4, 0xe90234c65a15e533})}, - {false, -195, - MType({0x97079feab7423d9b, 0xe1e0dda0b3d375a3, 0xed88f6bb355fa196})}, - {false, -195, - MType({0x22b519828722ce77, 0x5dab68307fedefcd, 0xf6a852513757dfbd})}, - {false, -195, - MType({0x66278c914a763228, 0xa112379749fd91b8, 0xfb410b64e6393477})}, - {false, -195, - MType({0x12b0b091e7b0299d, 0x1be2585c279c50a5, 0xffdfe15de3c01bac})}, - {false, -194, - MType({0x3f42ceed6e05646f, 0x18aa302171017dcb, 0x8242724a155219f3})}, - {false, -194, - MType({0xd146a4518aa0076f, 0xabc7e698502d43bf, 0x849812d0ccbb5cbd})}, - {false, -194, - MType({0x34708f4b01b4e73f, 0xc339089a51663370, 0x86f0dab1ab5822b6})}, - {false, -194, - MType({0x5e3e593143a3f512, 0x26f70b34ce5cf201, 0x894cd27d9f182c63})}, - {false, -194, - MType({0xb5f326771e3d87a9, 0x676f20a87ab433de, 0x8bac02e8ac3e09ac})}, - {false, -194, - MType({0x633dc078567bc8d9, 0x6db4169cc4b83bc3, 0x8e0e74caae062e24})}, - {false, -194, - MType({0x662d0eb20c51da4f, 0xcd3fdb2fad0d1fd6, 0x907431201c7f651a})}, - {false, -194, - MType({0x7fed29520fdf89d7, 0x49d03e163250d1d4, 0x92dd410ad7bfe103})}, - {false, -194, - MType({0xed5106d40e889904, 0x9ec7dc02d5e723b8, 0x9549add2f8a3c7e0})}, - {false, -194, - MType({0xcdbe2ebc07714f34, 0x34698d03a5442572, 0x97b980e7a743d71c})}, - {false, -194, - MType({0x1e9782e43af2d3d7, 0x522904d1e47f3de, 0x9a2cc3dff7548556})}, - {false, -194, - MType({0xfabfd5317e9bdd56, 0x791a72646c87b975, 0x9ca3807bca9fe93f})}, - {false, -194, - MType({0x2dc99e57977305af, 0x3826f190d655d736, 0x9f1dc0a4b9cea286})}, - {false, -194, - MType({0x5a4dfeb5b0db1f24, 0x544ab3e48199b299, 0xa19b8e6f03b60e45})}, - {false, -194, - MType({0x2888ece2bf37b7e9, 0xbe775fa82961114e, 0xa41cf41a83643487})}, - {false, -194, - MType({0xef4915fda0982302, 0x45798e5019e6c081, 0xa6a1fc13ad241953})}, - {false, -194, - MType({0x33a92c4634bdd6c, 0x91fb1ed0cdc4d1fb, 0xa92ab0f492b772bd})}, - {false, -194, - MType({0xe89863702c85cccb, 0x818b8b9cbbd17b71, 0xabb71d85ef05380d})}, - {false, -194, - MType({0x482ab24ae8fdf5a4, 0xa50c2fea60c5b3b2, 0xae474cc0397f0d4f})}, - {false, -194, - MType({0x682d5b55e9594eb3, 0x58ea34980ad8b720, 0xb0db49ccc1823c8e})}, - {false, -194, - MType({0xae8dceb953c096c0, 0x4b5f71941be508a3, 0xb3732006d1fbbba5})}, - {false, -194, - MType({0xfc1396a39c34fef3, 0x9e405fb8bcb1ff1d, 0xb60edafcdd99ad1d})}, - {false, -194, - MType({0xcff88d82b3417f9b, 0xf7e2ab36f09e9013, 0xb8ae8671b3d7dd6c})}, - {false, -194, - MType({0x6f1a4043a1a8a435, 0xc669639640c305bb, 0xbb522e5dbf37f63b})}, - {false, -194, - MType({0x6f1a4043a1a8a435, 0xc669639640c305bb, 0xbb522e5dbf37f63b})}, - {false, -194, - MType({0x6c4433809b0babe7, 0xa3dc9e464e98764b, 0xbdf9def04cf980ff})}, - {false, -194, - MType({0x38a1d9b9b9370d6d, 0xffd3256b59fa9c59, 0xc0a5a490dea95b5e})}, - {false, -194, - MType({0x60b092e62b5beb8a, 0xb0a2d48672a051a5, 0xc3558be085e3f4bc})}, - {false, -194, - MType({0x1065867f127536e0, 0xacb2ca5d4ca1c10e, 0xc609a1bb4aa98f59})}, - {false, -194, - MType({0x8030cfce4646062f, 0x43690b9e3cde0d01, 0xc8c1f3399ca7d33b})}, - {false, -194, - MType({0x8030cfce4646062f, 0x43690b9e3cde0d01, 0xc8c1f3399ca7d33b})}, - {false, -194, - MType({0xd806ff9947bc6ca7, 0x18b1fd60383f7e59, 0xcb7e8db1cfe04827})}, - {false, -194, - MType({0x65af114cbdb0193e, 0x248757e5f45af3d, 0xce3f7eb9a517c969})}, - {false, -194, - MType({0x3569862a1e8f9a4c, 0x7c4acd605be48bc1, 0xd104d427de7fbcc4})}, - {false, -194, - MType({0x94e3cbc5cd693dda, 0x58ff63629a92652c, 0xd3ce9c15e10ec927})}, - {false, -194, - MType({0x94e3cbc5cd693dda, 0x58ff63629a92652c, 0xd3ce9c15e10ec927})}, - {false, -194, - MType({0x1e0a73c970dbbf33, 0x6b49be3bd8c89f10, 0xd69ce4e16303fcdd})}, - {false, -194, - MType({0x59899d5040e21558, 0xe6dd603a881e9060, 0xd96fbd2e2814c9cc})}, - {false, -194, - MType({0x71549f0a4d78d49c, 0x89e281c98c1d705c, 0xdc4733e7cbcbfc8c})}, - {false, -194, - MType({0x71549f0a4d78d49c, 0x89e281c98c1d705c, 0xdc4733e7cbcbfc8c})}, - {false, -194, - MType({0xf4eee5981334e57, 0xdc0db7cf0cce9f32, 0xdf2358439aa5dd12})}, - {false, -194, - MType({0xd50afdf84e68b269, 0xfdf1c5b846db9dea, 0xe20439c27a7c01b8})}, - {false, -194, - MType({0xd95ac10b65558e44, 0x3dd7eab48869c401, 0xe4e9e832e2da0c05})}, - {false, -194, - MType({0xd95ac10b65558e44, 0x3dd7eab48869c401, 0xe4e9e832e2da0c05})}, - {false, -194, - MType({0xe9377fb1f3b453b6, 0x4e8fcc900b41daee, 0xe7d473b2e5db8f2a})}, - {false, -194, - MType({0xe772954c39d07f3b, 0x7593e1a9e9173599, 0xeac3ecb24a3ac7b4})}, - {false, -194, - MType({0xe772954c39d07f3b, 0x7593e1a9e9173599, 0xeac3ecb24a3ac7b4})}, - {false, -194, - MType({0xa6d10312a95362d4, 0xe7741396b49e1ce4, 0xedb863f4b73f982d})}, - {false, -194, - MType({0xd0d55aebaeb5abfc, 0xc8ba4f8f47b85a5b, 0xf0b1ea93f34675a7})}, - {false, -194, - MType({0xd0d55aebaeb5abfc, 0xc8ba4f8f47b85a5b, 0xf0b1ea93f34675a7})}, - {false, -194, - MType({0x7e1dea1275662695, 0x7007c1276821b705, 0xf3b09202359f9787})}, - {false, -194, - MType({0x54dc283e4f79339c, 0x7ee19afe6db7e324, 0xf6b46c0c8c8fdea1})}, - {false, -194, - MType({0x54dc283e4f79339c, 0x7ee19afe6db7e324, 0xf6b46c0c8c8fdea1})}, - {false, -194, - MType({0xf7844244016096c0, 0xedf54f37f6d4041f, 0xf9bd8add584687f0})}, - {false, -194, - MType({0x94a99151573d5249, 0xefe52ccf03e7dee0, 0xfccc00fedba4e6fb})}, - {false, -194, - MType({0x94a99151573d5249, 0xefe52ccf03e7dee0, 0xfccc00fedba4e6fb})}, - {false, -194, - MType({0x12b0b091e7b0299d, 0x1be2585c279c50a5, 0xffdfe15de3c01bac})}, - {false, -193, - MType({0xeba2ae5f7d1c7168, 0xe0b571f5c91b0445, 0x817c9fa643880404})}, - {false, -193, - MType({0xeba2ae5f7d1c7168, 0xe0b571f5c91b0445, 0x817c9fa643880404})}, - {false, -193, - MType({0x2db8874aa1eb0c3c, 0x7178594bef2def59, 0x830c17427ea55eca})}, - {false, -193, - MType({0x2db8874aa1eb0c3c, 0x7178594bef2def59, 0x830c17427ea55eca})}, - {false, -193, - MType({0xf3cb58bd1bbe04f0, 0x9a741bb171158d29, 0x849e6196487c1d1c})}, - {false, -193, - MType({0xd95b712663014da, 0x1a618264446cb495, 0x863388eb55ebd295})}, - {false, -193, - MType({0xd95b712663014da, 0x1a618264446cb495, 0x863388eb55ebd295})}, - {false, -193, - MType({0x2e66a10dfdce751, 0x71dbdbbec51d7657, 0x87cb97c3ff9eac18})}, - {false, -193, - MType({0x2e66a10dfdce751, 0x71dbdbbec51d7657, 0x87cb97c3ff9eac18})}, - {false, -193, - MType({0x84a2c0cd81dbcf53, 0xabe0b522230f7d13, 0x896698dce4cff76c})}, - {false, -193, - MType({0xae1f8a1def2acf5a, 0xd28e8adafea703b3, 0x8b04972e9d4d3011})}, - {false, -193, - MType({0xae1f8a1def2acf5a, 0xd28e8adafea703b3, 0x8b04972e9d4d3011})}, - {false, -193, - MType({0x8a02390202a4a59d, 0x208422d83be34b26, 0x8ca59def7b5cefc5})}, - {false, -193, - MType({0x8a02390202a4a59d, 0x208422d83be34b26, 0x8ca59def7b5cefc5})}, - {false, -193, - MType({0x420c16bd3939f912, 0xc385cf49402af0e4, 0x8e49b8955e3ffb8a})}, - {false, -193, - MType({0x420c16bd3939f912, 0xc385cf49402af0e4, 0x8e49b8955e3ffb8a})}, - {false, -193, - MType({0x8a1754a1ee7c990, 0xda982a614e12c6dd, 0x8ff0f2d7960a075c})}, - {false, -193, - MType({0xe77cb3d650c2718e, 0x38401fc1c1b5c2b, 0x919b58b0d999bbc8})}, - {false, -193, - MType({0xe77cb3d650c2718e, 0x38401fc1c1b5c2b, 0x919b58b0d999bbc8})}, - {false, -193, - MType({0x3c50b7234a381be8, 0xa9b55d3f16da746a, 0x9348f6614f821394})}, - {false, -193, - MType({0x3c50b7234a381be8, 0xa9b55d3f16da746a, 0x9348f6614f821394})}, - {false, -193, - MType({0xd31cd763e50a0231, 0x88d2d1473d4f7f4, 0x94f9d870aac256a5})}, - {false, -193, - MType({0xd31cd763e50a0231, 0x88d2d1473d4f7f4, 0x94f9d870aac256a5})}, - {false, -193, - MType({0x8eb2e675bc182d0d, 0x7c1e117dea19e9e5, 0x96ae0bb05c35d5bd})}, - {false, -193, - MType({0x8eb2e675bc182d0d, 0x7c1e117dea19e9e5, 0x96ae0bb05c35d5bd})}, - {false, -193, - MType({0x78c2d9cf6e98b1c1, 0x336db0630f536fb9, 0x98659d3dd9b12532})}, - {false, -193, - MType({0x78c2d9cf6e98b1c1, 0x336db0630f536fb9, 0x98659d3dd9b12532})}, - {false, -193, - MType({0x26ad30c543d1f34a, 0x8f8959ac0b7c9178, 0x9a209a84fbcff798})}, +// for i in range(-80, 81): +// r = 2^-21 * round( 2^21 / (1 + i*2^(-21)) ); +// s, m, e = RealField(128)(r).log10().sign_mantissa_exponent(); +// print("{false," if (s == -1) else "{true,", e, ", +// MType({", hex(m % 2^64), ",", hex((m >> 64) % 2^64), "})},"); +const Float128 LOG10_R3[161] = { + {true, -143, MType({0x54d7e49898ca0093, 0x8af8b9b322ba8c7d})}, + {true, -143, MType({0xc321bbf16665f29c, 0x893c06529deffc3d})}, + {true, -143, MType({0x8246df7140c3e4ae, 0x877f52e433ac7ec4})}, + {true, -143, MType({0x1deaa9e85780e4c1, 0x85c29f67e3ef35bc})}, + {true, -143, MType({0xcd8a5121a9162d0, 0x8405ebddaeb742cf})}, + {true, -143, MType({0xb10486fa4644308d, 0x824938459403c7a7})}, + {true, -143, MType({0x578a2f61eedd4be8, 0x808c849f93d3e5f0})}, + {true, -144, MType({0x715b4a491790e8a7, 0xfd9fa1d75c4d7ea6})}, + {true, -144, MType({0xefb6273a04c71573, 0xfa263a53c5f6eaf4})}, + {true, -144, MType({0x474d901560c17807, 0xf6acd2b464a25420})}, + {true, -144, MType({0x6b9a5deceb80ec57, 0xf3336af9384dfd7c})}, + {true, -144, MType({0x2665a32f7cc64f79, 0xefba032240f82a5d})}, + {true, -144, MType({0x17c8a67316659363, 0xec409b2f7e9f1e16})}, + {true, -144, MType({0xb62cdd3ef5c8673d, 0xe8c73320f1411bfa})}, + {true, -144, MType({0x4e4be6d5a4a07422, 0xe54dcaf698dc675e})}, + {true, -144, MType({0x32f86ff08c92e22, 0xe1d462b0756f4394})}, + {true, -144, MType({0xce31a0d27359396f, 0xde5afa4e86f7f3ee})}, + {true, -144, MType({0x7efc3180aee36373, 0xdae191d0cd74bbc1})}, + {true, -144, MType({0xbb894b1e0ce72fc4, 0xd768293748e3de5e})}, + {true, -144, MType({0x230f6c7270f8be, 0xd3eec081f9439f19})}, + {true, -144, MType({0x9f63aaa563e9a399, 0xd07557b0de924142})}, + {true, -144, MType({0xc2354e441015e7eb, 0xccfbeec3f8ce082d})}, + {true, -144, MType({0x67d22bcf5a452a4c, 0xc98285bb47f5372c})}, + {true, -144, MType({0x65c46fa3e3afea18, 0xc6091c96cc061190})}, + {true, -144, MType({0x67e63bbe1405c20d, 0xc28fb35684fedaab})}, + {true, -144, MType({0xf061a284212afbad, 0xbf1649fa72ddd5ce})}, + {true, -144, MType({0x57b0a1901625b539, 0xbb9ce08295a1464c})}, + {true, -144, MType({0xcc9d1c79d93a9a1e, 0xb82376eeed476f74})}, + {true, -144, MType({0x5440d7a131392da8, 0xb4aa0d3f79ce9499})}, + {true, -144, MType({0xca0572f7c9f7a7de, 0xb130a3743b34f90a})}, + {true, -144, MType({0xdfa464cb37fe6455, 0xadb7398d3178e019})}, + {true, -144, MType({0x1d26f48efb62e2e0, 0xaa3dcf8a5c988d17})}, + {true, -144, MType({0xe0e635a681d259e2, 0xa6c4656bbc924352})}, + {true, -144, MType({0x5f8b022f27cbda35, 0xa34afb315164461d})}, + {true, -144, MType({0xa40df5ca390a0465, 0x9fd190db1b0cd8c6})}, + {true, -144, MType({0x8fb76866f01c4f2d, 0x9c582669198a3e9e})}, + {true, -144, MType({0xda1f690c752fdeff, 0x98debbdb4cdabaf4})}, + {true, -144, MType({0x112db8a3dc07ee78, 0x95655131b4fc9119})}, + {true, -144, MType({0x9919c4c22125c79e, 0x91ebe66c51ee045a})}, + {true, -144, MType({0xac6aa27226204db3, 0x8e727b8b23ad5808})}, + {true, -144, MType({0x5bf708fead2b1780, 0x8af9108e2a38cf72})}, + {true, -144, MType({0x8ee54cbc53cd19ed, 0x877fa575658eade6})}, + {true, -144, MType({0x2ab59d38cc6e2c5, 0x84063a40d5ad36b4})}, + {true, -144, MType({0x4b0eaf0a99286378, 0x808ccef07a92ad29})}, + {true, -145, MType({0xa448b11f012c975c, 0xfa26c708a87aa929})}, + {true, -145, MType({0xb0a1d584117de73b, 0xf333eff8c556e089})}, + {true, -145, MType({0xe890f9fb57fdabb6, 0xec4118b14bb6870e})}, + {true, -145, MType({0x261d48c71e693130, 0xe54e41323b962355})}, + {true, -145, MType({0xefecdd48ed894c32, 0xde5b697b94f23bf7})}, + {true, -145, MType({0x7944b9957598a88a, 0xd768918d57c75792})}, + {true, -145, MType({0xa208bc0875093645, 0xd075b9678411fcbf})}, + {true, -145, MType({0xf6bb94d89da8b432, 0xc982e10a19ceb219})}, + {true, -145, MType({0xb07ebbab782457b0, 0xc290087518f9fe3b})}, + {true, -145, MType({0xb512652945eb9165, 0xbb9d2fa8819067be})}, + {true, -145, MType({0x96d57890e171eea5, 0xb4aa56a4538e753c})}, + {true, -145, MType({0x94c5854b9cd01726, 0xadb77d688ef0ad4e})}, + {true, -145, MType({0x9a7eb8811ec3e6bb, 0xa6c4a3f533b3968d})}, + {true, -145, MType({0x403bd2ab3e0fa2d7, 0x9fd1ca4a41d3b792})}, + {true, -145, MType({0xcad61d29db384b6b, 0x98def067b94d96f4})}, + {true, -145, MType({0x2bc55fd6b8a306ec, 0x91ec164d9a1dbb4d})}, + {true, -145, MType({0x11fd6995111a927, 0x8af93bfbe440ab33})}, + {true, -145, MType({0x959a26faac7e5494, 0x8406617297b2ed3d})}, + {true, -146, MType({0xc10eab7266ac6bc0, 0xfa270d6368e21007})}, + {true, -146, MType({0xbb178b90026b2b2, 0xec41577274ef0439})}, + {true, -146, MType({0xac3bfd925e6b33e1, 0xde5ba1125385c43b})}, + {true, -146, MType({0x9d0a01a95b355319, 0xd075ea43049f5d3b})}, + {true, -146, MType({0x31b3b7b20a6a6496, 0xc29033048834dc64})}, + {true, -146, MType({0x170da891504620f4, 0xb4aa7b56de3f4ee0})}, + {true, -146, MType({0x53289e84744549cb, 0xa6c4c33a06b7c1d9})}, + {true, -146, MType({0x45519048b0ce7e7f, 0x98df0aae01974279})}, + {true, -146, MType({0xa6118c42bf99407e, 0x8af951b2ced6dde8})}, + {true, -147, MType({0xe5b474cc5a64cf6, 0xfa273090dcdf429f})}, + {true, -147, MType({0xa74dab3bd6067bc7, 0xde5bbcddc0b533aa})}, + {true, -147, MType({0x9f73f4e37357341b, 0xc290484c4921a941})}, + {true, -147, MType({0x31bf5d5f815220e7, 0xa6c4d2dc7616bdb0})}, + {true, -147, MType({0x4b987ca5fca242d7, 0x8af95c8e47868b41})}, + {true, -148, MType({0x19be3fabd93832c5, 0xde5bcac37ac6587d})}, + {true, -148, MType({0x8fd43f0c9ce444d3, 0xa6c4daadaf3d75e0})}, + {true, -149, MType({0x61cd853e796bc2c, 0xde5bd1b658ad4676})}, + {true, -150, MType({0x87d6afabfba0644f, 0xde5bd52fc7d8545f})}, + {false, 0, MType({0x0, 0x0})}, + {false, -150, MType({0xa9bf32001043629d, 0xde5bdc22a69d9e19})}, + {false, -149, MType({0x8014f0f360272d82, 0xde5bdf9c1637d9ef})}, + {false, -148, MType({0xfe94a02fc639c0e3, 0xa6c4ea5024795bd2})}, + {false, -148, MType({0xbee710a5ace7c8d4, 0xde5be68ef5db7f99})}, + {false, -147, MType({0x1a778d8100437e4f, 0x8af972453faf11e8})}, + {false, -147, MType({0x97d773f8992f7051, 0xa6c4f221608e89fe})}, + {false, -147, MType({0xc9ee5841a3afa95, 0xc29072dbdd9a0dd5})}, + {false, -147, MType({0x7b644b13993cf4ef, 0xde5bf474b6df8331})}, + {false, -147, MType({0x3448f66e2bd7a0ca, 0xfa2776ebec6ccfdb})}, + {false, -146, MType({0x6a7ca5f1a87a1a3c, 0x8af97d20bf27eccd})}, + {false, -146, MType({0x245675fe3061108f, 0x98df3f3ab64b431d})}, + {false, -146, MType({0x64136e97019d0a3b, 0xa6c501c3dba75dc2})}, + {false, -146, MType({0x6cdadac4d6925bd4, 0xb4aac4bc2f432fa3})}, + {false, -146, MType({0x2899e23791d29632, 0xc2908823b125aba7})}, + {false, -146, MType({0x28039e1f0323a4c1, 0xd0764bfa6155c4b5})}, + {false, -146, MType({0xa2912e03afc8cc28, 0xde5c10403fda6db5})}, + {false, -146, MType({0x7681cc9f9e0d89f9, 0xec41d4f54cba9991})}, + {false, -146, MType({0x28dae4b7241255e1, 0xfa279a1987fd3b32})}, + {false, -145, MType({0xf2b412f8dceda28e, 0x8406afd678d4a2c0})}, + {false, -145, MType({0xbf5dccd967504857, 0x8af992d7c4e2d5b5})}, + {false, -145, MType({0x3716dbf950b07f85, 0x91ec7610a82cafed})}, + {false, -145, MType({0x69eebe0b8e5b18e1, 0x98df598122b5aadd})}, + {false, -145, MType({0xbb583ce65af56beb, 0x9fd23d2934813ffc})}, + {false, -145, MType({0xe22978efa7a962a0, 0xa6c52108dd92e8c1})}, + {false, -145, MType({0xe89bf3898ef27836, 0xadb805201dee1ea3})}, + {false, -145, MType({0x2c4c997ec90bab0b, 0xb4aae96ef5965b1a})}, + {false, -145, MType({0x5e3bcd6f21fe6224, 0xbb9dcdf5648f179c})}, + {false, -145, MType({0x82cd723bf1524680, 0xc290b2b36adbcda2})}, + {false, -145, MType({0xf1c8f574935e109b, 0xc98397a9087ff6a4})}, + {false, -145, MType({0x565959c2e4394a59, 0xd0767cd63d7f0c1c})}, + {false, -145, MType({0xaf0d4157bc4f05be, 0xd769623b09dc8781})}, + {false, -145, MType({0x4dd6f8576e9188b8, 0xde5c47d76d9be24e})}, + {false, -145, MType({0xd80c7f46484eee3d, 0xe54f2dab68c095fb})}, + {false, -145, MType({0x4667957512a6bd26, 0xec4213b6fb4e1c04})}, + {false, -145, MType({0xe505c36d95a074fa, 0xf334f9fa2547ede1})}, + {false, -145, MType({0x5368655f1ce3110b, 0xfa27e074e6b1850f})}, + {false, -144, MType({0xc23a5ac57f06c112, 0x808d63939fc72d83})}, + {false, -144, MType({0xdf39eb5890580f93, 0x8406d70897f0f4a2})}, + {false, -144, MType({0xcd896f3e43f38669, 0x87804a995bd7d4a2})}, + {false, -144, MType({0x83b16ff7eecace8c, 0x8af9be45eb7d8a41})}, + {false, -144, MType({0x21ec7ae8ffa1531d, 0x8e73320e46e3d23d})}, + {false, -144, MType({0xf227268d464ae907, 0x91eca5f26e0c6953})}, + {false, -144, MType({0x680017af3bbaf2d3, 0x956619f260f90c44})}, + {false, -144, MType({0x20c8069e4ae400de, 0x98df8e0e1fab77cd})}, + {false, -144, MType({0xe381c4651a67ee13, 0x9c590245aa2568ac})}, + {false, -144, MType({0xa0e23fffd718794e, 0x9fd2769900689ba2})}, + {false, -144, MType({0x73508b927f485b97, 0xa34beb082276cd6d})}, + {false, -144, MType({0x9ee5e19f2eecdb55, 0xa6c55f931051bacc})}, + {false, -144, MType({0x916daa3c6c8fdc9d, 0xaa3ed439c9fb207f})}, + {false, -144, MType({0xe265804b77126ed3, 0xadb848fc4f74bb45})}, + {false, -144, MType({0x52fd36ae943fd7b4, 0xb131bddaa0c047df})}, + {false, -144, MType({0xce16dd7f60311bf6, 0xb4ab32d4bddf830b})}, + {false, -144, MType({0x6846c7451d8105ac, 0xb824a7eaa6d4298b})}, + {false, -144, MType({0x5fd38e2b0650a884, 0xbb9e1d1c5b9ff81e})}, + {false, -144, MType({0x1cb619369e1c641f, 0xbf179269dc44ab85})}, + {false, -144, MType({0x3099a17e0461648c, 0xc29107d328c40080})}, + {false, -144, MType({0x56dbb75e4813a12b, 0xc60a7d58411fb3d0})}, + {false, -144, MType({0x748c47b1bbe45a07, 0xc983f2f925598236})}, + {false, -144, MType({0x986da1064b5913e1, 0xccfd68b5d5732873})}, + {false, -144, MType({0xfaf478d3d0b31300, 0xd076de8e516e6348})}, + {false, -144, MType({0xfe47f0b26ba754ff, 0xd3f05482994cef77})}, + {false, -144, MType({0x2e419b90d8e709b7, 0xd769ca92ad1089c2})}, + {false, -144, MType({0x406d82eaca788b6f, 0xdae340be8cbaeee9})}, + {false, -144, MType({0x140a2bff40e0d670, 0xde5cb706384ddbaf})}, + {false, -144, MType({0xb2089d06e51d8034, 0xe1d62d69afcb0cd5})}, + {false, -144, MType({0x4d0c626a636f2e4f, 0xe54fa3e8f3343f1f})}, + {false, -144, MType({0x416b93f8c6f48d30, 0xe8c91a84028b2f4e})}, + {false, -144, MType({0x152eda1dd615c6f5, 0xec42913addd19a25})}, + {false, -144, MType({0x781173186fc07a66, 0xefbc080d85093c66})}, + {false, -144, MType({0x43813830e974324d, 0xf3357efbf833d2d5})}, + {false, -144, MType({0x7a9ea2ef6e1f5d41, 0xf6aef60637531a34})}, + {false, -144, MType({0x4a3cd2525dccc623, 0xfa286d2c4268cf47})}, + {false, -144, MType({0x8e19004ae218d5d, 0xfda1e46e1976aed1})}, + {false, -143, MType({0x9b62aaca25d5d18a, 0x808dade5de3f3aca})}, + {false, -143, MType({0xbee9a8d43e00613c, 0x824a69a295c0f02b})}, + {false, -143, MType({0xd8d4b69c2056f729, 0x8407256d334155ed})}, + {false, -143, MType({0xe7cc28605d7bb77e, 0x85c3e145b6c14a72})}, + {false, -143, MType({0xff51b4bdc834a8f1, 0x87809d2c2041ac1c})}, + {false, -143, MType({0x47c0774aa81c3561, 0x893d59206fc3594e})}, + {false, -143, MType({0xfe4cf331ecb9eb62, 0x8afa1522a5473068})}, +}; + +// Range reduction - Step 4 +// r(k) = 2^-28 round(2^28 / (1 + k*2^-28)) for k = -65 .. 64. +// Output range: +// [-0x1.0002143p-29 , 0x1p-29] + +// We store S[i] = 2^28 (r(i - 65) - 1). +constexpr int64_t S4[130] = { + 0x41, 0x40, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 0x37, + 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f, 0x2e, 0x2d, 0x2c, + 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, + 0x20, 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16, + 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0xf, 0xe, 0xd, 0xc, 0xb, + 0xa, 0x9, 0x8, 0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0, + -0x1, -0x2, -0x3, -0x4, -0x5, -0x6, -0x7, -0x8, -0x9, -0xa, -0xb, + -0xc, -0xd, -0xe, -0xf, -0x10, -0x11, -0x12, -0x13, -0x14, -0x15, -0x16, + -0x17, -0x18, -0x19, -0x1a, -0x1b, -0x1c, -0x1d, -0x1e, -0x1f, -0x20, -0x21, + -0x22, -0x23, -0x24, -0x25, -0x26, -0x27, -0x28, -0x29, -0x2a, -0x2b, -0x2c, + -0x2d, -0x2e, -0x2f, -0x30, -0x31, -0x32, -0x33, -0x34, -0x35, -0x36, -0x37, + -0x38, -0x39, -0x3a, -0x3b, -0x3c, -0x3d, -0x3e, -0x3f, -0x40, }; -// -log10(r) for further range reduction steps, generated by SageMath with: +// -log10(r) for the fourth step, generated by SageMath with: // -// RR = RealField(192); -// for i in range(5): -// N = 11 + 4*i; -// print("{"); -// for j in range(-2^4, 2^4): -// r = 2^(-N) * round(2^(N) * ( 1 + (j + 0.5)*2^(-N) - 2^(-2*N-1) ) / ((1 + -// j * 2^(-N)) * (1 + (j + 1)*2^(-N)))); a = -RR(r).log10(); if j in [0, -// -1]: -// r = 1; a = RR(0); -// s, m, e = a.sign_mantissa_exponent() -// sgn = "{false," if s == 1 else "{true,"; -// print(sgn, e, ", MType({", hex(m % 2^64), ",", hex((m >> 64) % 2^64), -// ",", hex((m >> 128) % 2^64), "})},"); -// print("},"); -const Float192 LOG10_RR[R_STEPS][R_SIZES] = { - { - {true, -200, - MType({0xf52b7aea9ca0c476, 0xdd4a47e1490df56, 0xdd7ea3910f69332e})}, - {true, -200, - MType({0x11c54af8b7b5ac0, 0xbe14368ead9df21c, 0xcfb39f5a164f371c})}, - {true, -200, - MType({0xdc8b8e1f46c98b22, 0xb46a6050fcd513ca, 0xc1e6e4dcf45e0ee0})}, - {true, -200, - MType({0x10c91fa8440cf6a8, 0x799e2aecea385841, 0xb41873accfbaba29})}, - {true, -200, - MType({0xefff2920f96d3591, 0x3440eb8005ad171b, 0xa6484b5ca5f7eaea})}, - {true, -200, - MType({0xaa51f382c80587cb, 0x21e85464267c47a4, 0x98766b7f4c01d932})}, - {true, -200, - MType({0xaf1454629688e40a, 0xee383c5f131898c4, 0x8aa2d3a76e0a0a79})}, - {true, -201, - MType({0xf128ae4671df433, 0x15022fc12f1747d4, 0xf99b06cf1ee618b9})}, - {true, -201, - MType({0x511d8d64285691ec, 0x411e70646c13ae93, 0xddecf4a415784564})}, - {true, -201, - MType({0xd9e8330f453fac1c, 0x662bb5e078c532bf, 0xc23b6ff222d9d207})}, - {true, -201, - MType({0xa9d37fde93b3c989, 0xebcfc062f09deb23, 0xa68677dd5801ce9b})}, - {true, -201, - MType({0xe9eadfa1556bcaec, 0xbfdd2c7f388fc013, 0x8ace0b8973a63413})}, - {true, -202, - MType({0x743a88400b3b04bc, 0xc21595e745f1fa15, 0xde245433c425b5c5})}, - {true, -202, - MType({0xf50e04c0bd73e444, 0x663cf2b27e8f1ffa, 0xa6a5a5637a00afdc})}, - {true, -203, - MType({0xf860837f66c35a6a, 0xba0324530edaa03e, 0xde4011cf2daaff31})}, - {false, 0, MType({0x0, 0x0, 0x0})}, - {false, 0, MType({0x0, 0x0, 0x0})}, - {false, -204, - MType({0x8319f4e45b099e86, 0x20fa8a73c585f633, 0xde69bf8f58005dfc})}, - {false, -203, - MType({0x58e9d6dee00a8fc3, 0x35e3298f4bb2aa0a, 0xde77a8c714b08d28})}, - {false, -202, - MType({0xc6b4c904be2cbf01, 0xa1e66c6203725d4f, 0xa6e42f3ccf49959d})}, - {false, -202, - MType({0xebc8b4278d3f93e9, 0x5ad3480ccfbe988f, 0xde93822dfe812587})}, - {false, -201, - MType({0x9e52f5c983d9caa4, 0xe5f7c52cdf119d4, 0x8b24e77b0cb60a84})}, - {false, -201, - MType({0x9a29985625bf9936, 0x84e42dd54c2ff44e, 0xa7038baa64c5cd39})}, - {false, -201, - MType({0x15c143896f774901, 0xde013ef4ba5abcfa, 0xc2e5ae853064a921})}, - {false, -201, - MType({0x8c6b1043496971e, 0x8f6c475cc382401c, 0xdecb50ebece5e146})}, - {false, -201, - MType({0x95457befdc15d5a7, 0x64a67faf3f1c74c2, 0xfab473bf6c2589b9})}, - {false, -200, - MType({0x825120e3dbb4f086, 0x341aa1df5e8fab33, 0x8b508bf06a597f35})}, - {false, -200, - MType({0xc69ade976589376a, 0x8b19159a7036ac6c, 0x99489f18d0fdba55})}, - {false, -200, - MType({0x132b76e2a5ed5ce1, 0x7b8b2852580ae3e2, 0xa74273c9d23a53b9})}, - {false, -200, - MType({0x6f0c9495185af64, 0xe9ad89ebfeaf5a02, 0xb53e0a7480e3cf3c})}, - {false, -200, - MType({0x3dc11a3e41e693ee, 0xe12996e107931f4b, 0xc33b638a1a7dc81d})}, - {false, -200, - MType({0x2ce27c62f7c5d30e, 0xb43caf8e7b891066, 0xd13a7f7c07506f7d})}, - }, - { - {true, -204, - MType({0xea57bded8e15fa61, 0x634cea6750617a91, 0xde4df4140b42822f})}, - {true, -204, - MType({0x8a2e8bb53b241b41, 0x9185547f24195fab, 0xd069e52741db93b6})}, - {true, -204, - MType({0x265b41c72630e265, 0xfbd7e970aef9dbb8, 0xc285ba757feb2781})}, - {true, -204, - MType({0xd2e480f950aea396, 0xe820a1a6f319285a, 0xb4a173fe56691147})}, - {true, -204, - MType({0xb3300685a98f7031, 0x9aedc1c1ba7d0694, 0xa6bd11c1564a8ace})}, - {true, -204, - MType({0x407aba2445f75697, 0x89de4989587519ca, 0x98d893be108233d7})}, - {true, -204, - MType({0xbe4f7e3cbefc71ce, 0x8d306ba207233c43, 0x8af3f9f41600120a})}, - {true, -205, - MType({0x5449f3ae334e8294, 0x2100088006aeff92, 0xfa1e88c5ef6321c2})}, - {true, -205, - MType({0x2245be0033c6dafe, 0x856a0a3a00fcf3c1, 0xde54e6148d030322})}, - {true, -205, - MType({0xf8b7f31304662b13, 0x8a4399de0be1c455, 0xc28b0bd326b035f2})}, - {true, -205, - MType({0x5abacdedb1dc0b2c, 0xb3a2c1407cf6d38d, 0xa6c0fa00de35f314})}, - {true, -205, - MType({0x874695793b5a312e, 0x220af90d74ea17c7, 0x8af6b09cd55a3e68})}, - {true, -206, - MType({0x70a9c05700a3f2c5, 0xd791cf6a70c3a504, 0xde585f4c5bbbcd3d})}, - {true, -206, - MType({0x1f465fbffe379fdf, 0xe95b52a2781c25e3, 0xa6c2ee3812f90a28})}, - {true, -207, - MType({0x35af2ed67a089e4, 0x10a633f2c4a8ea22, 0xde5a1bf627b1f68f})}, - {false, 0, MType({0x0, 0x0, 0x0})}, - {false, 0, MType({0x0, 0x0, 0x0})}, - {false, -208, - MType({0xe0faf0a837063878, 0x140a2bff40e0d66f, 0xde5cb706384ddbaf})}, - {false, -207, - MType({0xd660ff616f334614, 0xed4a68e5e6e83dde, 0xde5d95658a729eab})}, - {false, -206, - MType({0x542eeb05597ecdea, 0x7c9dc000df79edde, 0xa6c6d6d56238dd6e})}, - {false, -206, - MType({0x5f8e2902ab25d093, 0x3281f1872cdbee94, 0xde5f522b21e3e25a})}, - {false, -205, - MType({0xba7cb3452f07c347, 0x292ef5f6fbe96c00, 0x8afc1e5ae08b4643})}, - {false, -205, - MType({0xde1cc00ce5b7249c, 0xf1466edaa96e356d, 0xa6c8cb3b7e5bbbfd})}, - {false, -205, - MType({0xa521ef720e08d8fe, 0x936a112cb6265f7e, 0xc295afb848dbd759})}, - {false, -205, - MType({0x1d1317f34a2fba9e, 0x8a607fd695dfc3d9, 0xde62cbd21e895473})}, - {false, -205, - MType({0x9c74fa60d5502c53, 0x65a49326981bdf3f, 0xfa301f89dde726b4})}, - {false, -204, - MType({0x4295ea162700a15d, 0xc36b8713ceefe2de, 0x8afed57032bebc7c})}, - {false, -204, - MType({0x10e84795ee07f1c, 0x7068ee550f5ffb37, 0x98e5b6eb49ecd6df})}, - {false, -204, - MType({0xf71013dc630dfafa, 0x5c2e76c953e3e3e5, 0xa6ccb436a3c72fa4})}, - {false, -204, - MType({0x61fc137c9dce9644, 0xb3425e818888a098, 0xb4b3cd52af99afe6})}, - {false, -204, - MType({0xe923dcabcfbadd8e, 0x8e4950fa5c943bbe, 0xc29b023fdcb2dccf})}, - {false, -204, - MType({0xd941d748e2a23bcc, 0xd4d3796d93d6750b, 0xd08252fe9a63d7aa})}, - }, - { - {true, -208, - MType({0x22058fdb723bb37, 0xce31a0d27359396f, 0xde5afa4e86f7f3ee})}, - {true, -208, - MType({0x2e22d8a1e7a512a1, 0x9f63aaa563e9a399, 0xd07557b0de924142})}, - {true, -208, - MType({0xd1fffbb5f7c92f10, 0x67e63bbe1405c20c, 0xc28fb35684fedaab})}, - {true, -208, - MType({0x2473a71714b9ef53, 0x5440d7a131392da8, 0xb4aa0d3f79ce9499})}, - {true, -208, - MType({0xdec055ae33e59ad5, 0xe0e635a681d259e1, 0xa6c4656bbc924352})}, - {true, -208, - MType({0x953365af70272280, 0xda1f690c752fdefe, 0x98debbdb4cdabaf4})}, - {true, -208, - MType({0xc6c161d92abe9aa4, 0x5bf708fead2b177f, 0x8af9108e2a38cf72})}, - {true, -209, - MType({0x78732843e6506315, 0xa448b11f012c975c, 0xfa26c708a87aa929})}, - {true, -209, - MType({0x863d53d84705d0ae, 0xefecdd48ed894c31, 0xde5b697b94f23bf7})}, - {true, -209, - MType({0x87704029104c21a9, 0xb07ebbab782457af, 0xc290087518f9fe3b})}, - {true, -209, - MType({0x4adb1df9649c50c1, 0x9a7eb8811ec3e6bb, 0xa6c4a3f533b3968d})}, - {true, -209, - MType({0xcfe3880042e86013, 0x11fd6995111a926, 0x8af93bfbe440ab33})}, - {true, -210, - MType({0x2cbf7a2e7b9cbcf0, 0xac3bfd925e6b33e1, 0xde5ba1125385c43b})}, - {true, -210, - MType({0x4d418d19762cbd66, 0x53289e84744549cb, 0xa6c4c33a06b7c1d9})}, - {true, -211, - MType({0x4c3b3ad870a5dd12, 0xa74dab3bd6067bc7, 0xde5bbcddc0b533aa})}, - {false, 0, MType({0x0, 0x0, 0x0})}, - {false, 0, MType({0x0, 0x0, 0x0})}, - {false, -212, - MType({0x29423084899fc9b9, 0xbee710a5ace7c8d4, 0xde5be68ef5db7f99})}, - {false, -211, - MType({0x1c57cf04091e59cc, 0x7b644b13993cf4ef, 0xde5bf474b6df8331})}, - {false, -210, - MType({0xd259a65cb34a4a8a, 0x64136e97019d0a3a, 0xa6c501c3dba75dc2})}, - {false, -210, - MType({0x6f497708cc18c4d8, 0xa2912e03afc8cc28, 0xde5c10403fda6db5})}, - {false, -209, - MType({0x865e042dd50e1d3a, 0xbf5dccd967504856, 0x8af992d7c4e2d5b5})}, - {false, -209, - MType({0xe1702b0f17301f13, 0xe22978efa7a9629f, 0xa6c52108dd92e8c1})}, - {false, -209, - MType({0x74a88aedf1375fb4, 0x82cd723bf1524680, 0xc290b2b36adbcda2})}, - {false, -209, - MType({0xa923a00c40053158, 0x4dd6f8576e9188b7, 0xde5c47d76d9be24e})}, - {false, -209, - MType({0x923113e7e6eec47e, 0x5368655f1ce3110a, 0xfa27e074e6b1850f})}, - {false, -208, - MType({0xee64cf0bae6dd4c9, 0x83b16ff7eecace8b, 0x8af9be45eb7d8a41})}, - {false, -208, - MType({0x782dbb6881f2d3d, 0x20c8069e4ae400de, 0x98df8e0e1fab77cd})}, - {false, -208, - MType({0xff9e92ff9157f7ff, 0x9ee5e19f2eecdb54, 0xa6c55f931051bacc})}, - {false, -208, - MType({0x4260c63c04224e80, 0xce16dd7f60311bf6, 0xb4ab32d4bddf830b})}, - {false, -208, - MType({0xbf40b2a151280765, 0x3099a17e0461648b, 0xc29107d328c40080})}, - {false, -208, - MType({0xb32695665b8f1329, 0xfaf478d3d0b312ff, 0xd076de8e516e6348})}, - }, - { - {true, -212, - MType({0xdaf98ea8088ccd55, 0x19be3fabd93832c4, 0xde5bcac37ac6587d})}, - {true, -212, - MType({0x92832d76e51450a5, 0x88a86b30027dc8a5, 0xd0760ee7b9136936})}, - {true, -212, - MType({0xdd67de1487eb3913, 0xc61c028b8f230f14, 0xc29052f02bebe878})}, - {true, -212, - MType({0x8b5c1ba51e27536f, 0xb8cfce8fa982ea7, 0xb4aa96dcd34f6716})}, - {true, -212, - MType({0xe1a1b61dba0d85b7, 0x8fd43f0c9ce444d2, 0xa6c4daadaf3d75e0})}, - {true, -212, - MType({0x60e206e644f9e560, 0x872f9b3fd2141246, 0x98df1e62bfb5a5aa})}, - {true, -212, - MType({0xeef14d02362d0513, 0x2341d13c21a7d8cf, 0x8af961fc04b78746})}, - {true, -213, - MType({0xb56b5c514a13e254, 0x26251c2ccc00d194, 0xfa274af2fc85570b})}, - {true, -213, - MType({0x60d8b357006a3fed, 0x61cd853e796bc2c, 0xde5bd1b658ad4676})}, - {true, -213, - MType({0xa90e9309cbc1b814, 0x3a0de60782dd1939, 0xc29058421de5fe71})}, - {true, -213, - MType({0xb6bc3ab198cec5a2, 0x10652e9b1ce538bb, 0xa6c4de964c2ea0a1})}, - {true, -213, - MType({0x27d91560ba3c3289, 0xd259757215d9aa0d, 0x8af964b2e3864ea9})}, - {true, -214, - MType({0xef6374ae583f4c18, 0x87d6afabfba0644e, 0xde5bd52fc7d8545f})}, - {true, -214, - MType({0x4bf40373e818d7f5, 0x47ca9999c73441f5, 0xa6c4e08a9abea9ae})}, - {true, -215, - MType({0x256483d247de2b54, 0xaf6e93be8e4c1764, 0xde5bd6ec7f7bc110})}, - {false, 0, MType({0x0, 0x0, 0x0})}, - {false, 0, MType({0x0, 0x0, 0x0})}, - {false, -216, - MType({0x5f6593112c03bf0b, 0xd5c0ebcf0fa0221e, 0xde5bd98793024346})}, - {false, -215, - MType({0x11b7b6679d212c54, 0x6d0063a923dd0cc6, 0xde5bda65eede65ed})}, - {false, -214, - MType({0x6079e21db1a5b651, 0xc424c8976e2ebcfa, 0xa6c4e473380da326})}, - {false, -214, - MType({0x8a7f3f059746be25, 0xa9bf32001043629c, 0xde5bdc22a69d9e19})}, - {false, -213, - MType({0xc8dbe969fc9bb1cd, 0x9e8e77fa22e00248, 0x8af96a20a1907043})}, - {false, -213, - MType({0xe129bb635500e8db, 0xaf3be9e7aa56d682, 0xa6c4e66786cc9393})}, - {false, -213, - MType({0xea8e87193d810fa0, 0xfc3aff5aaf056566, 0xc29062e603041758})}, - {false, -213, - MType({0x254d7de51cd5637d, 0x8014f0f360272d82, 0xde5bdf9c1637d9ef})}, - {false, -213, - MType({0xe9795a136f5856c, 0x3a891f89bcf72a40, 0xfa275c89c068b9b3})}, - {false, -212, - MType({0x3c5338931e9d2409, 0x18468a2ba2fa5549, 0x8af96cd780cbca80})}, - {false, -212, - MType({0x3ab6a381bda506d5, 0x362640905714e443, 0x98df2b85ece2a519})}, - {false, -212, - MType({0x13b57109141a8764, 0xfe94a02fc639c0e3, 0xa6c4ea5024795bd2})}, - {false, -212, - MType({0xc613ec4aff62b164, 0x7bddaab60665b883, 0xb4aaa93627905ddb})}, - {false, -212, - MType({0x29f60bd76dda9de7, 0xbae8765350c99434, 0xc2906837f6281a60})}, - {false, -212, - MType({0x6d1b70f85e1ebdd6, 0xcb372dd0da70965b, 0xd076275590410090})}, - }, - { - {true, -216, - MType({0xcf260846db91386b, 0x81645201b36e17b9, 0xde5bd7cadb50f0d8})}, - {true, -216, - MType({0x8f96908bc0be4701, 0xcdea7b1a0dc7ad41, 0xd0761a5b34fd720c})}, - {true, -216, - MType({0x71e2e36ca8d985f3, 0x5ce6604b0911c5ed, 0xc2905ce9d1f24872})}, - {true, -216, - MType({0xdaf377e6a6fc292b, 0x6e0982bd8d96ee, 0xb4aa9f76b22f739a})}, - {true, -216, - MType({0xf97df5dd10eab18e, 0x8a9754fe0c0073a6, 0xa6c4e201d5b4f314})}, - {true, -216, - MType({0x260badb439a3192f, 0xcd77f7489d9ef50b, 0x98df248b3c82c672})}, - {true, -216, - MType({0x35f8aeb949a552f2, 0x9b257b3ce3f82109, 0x8af96712e698ed45})}, - {true, -217, - MType({0x82d6f89adeda85fe, 0x8b6a840831c123d7, 0xfa275331a7eece3b})}, - {true, -217, - MType({0xb88ac395452a99d1, 0x3e79062c7cbb3b7c, 0xde5bd83a093c6718})}, - {true, -217, - MType({0x8416ca30683117d1, 0xf3a098743d20fb63, 0xc2905d3ef11aa442})}, - {true, -217, - MType({0xe98fafcacc5781ed, 0x4f0b030a9742eaff, 0xa6c4e2405f8984dd})}, - {true, -217, - MType({0x9dc90f008c47f3e0, 0xf4e1bab83f55f5a0, 0x8af9673e54890808})}, - {true, -218, - MType({0x1ff62cfc0b87b23a, 0x129bc1c6f293726e, 0xde5bd871a03259cf})}, - {true, -218, - MType({0xb2b2c5c7e8e3dd1b, 0x60f08720313daa3e, 0xa6c4e25fa473e535})}, - {true, -219, - MType({0x4a6c56a5be458d59, 0x3a25757e00f4e3a0, 0xde5bd88d6bad6110})}, - {false, 0, MType({0x0, 0x0, 0x0})}, - {false, 0, MType({0x0, 0x0, 0x0})}, - {false, -220, - MType({0x3f16581bde8d9c4a, 0x225916c2b3f33c90, 0xde5bd8b71ce5fd51})}, - {false, -219, - MType({0x8d1575503bb9c7fd, 0x44397830931fddc, 0xde5bd8c502a38b5e})}, - {false, -218, - MType({0x91d4a95df896a79f, 0xe454dec82bde52e4, 0xa6c4e29e2e48d4cc})}, - {false, -218, - MType({0x242c88441091cf56, 0xa6e2721f2afc3cce, 0xde5bd8e0ce1eae6a})}, - {false, -217, - MType({0x9b6ef45b7cbebc03, 0x80bf0ff2f6cd9f92, 0x8af967953069aa22})}, - {false, -217, - MType({0x7fe96798a2b597a7, 0x55ee1480619827c4, 0xa6c4e2bd7333640c})}, - {false, -217, - MType({0xedc6a1463ce32849, 0x2ed8ba8c6fa81c97, 0xc2905de92f6c85d1})}, - {false, -217, - MType({0xd59f31668df9feb7, 0x6759c94e2d017fac, 0xde5bd9186515104f})}, - {false, -217, - MType({0x337d83d075e0c1ab, 0x5b4c5b5f180b9fe1, 0xfa27544b142d0465})}, - {false, -216, - MType({0x390379ad9871c8a7, 0xb345ef5d90dd6545, 0x8af967c09e5a3178})}, - {false, -216, - MType({0x73d9d08521f9533d, 0xf27a0a6056dcfe57, 0x98df255d6f559668})}, - {false, -216, - MType({0xb70a87a69080a500, 0x99308918494a4a1f, 0xa6c4e2fbfd08b172})}, - {false, -216, - MType({0x8995c0b3074c289d, 0xd5579f970cf000a8, 0xb4aaa09c47738304})}, - {false, -216, - MType({0x72650f85eed7af38, 0xd4ddab9f8032bbab, 0xc2905e3e4e960b8e})}, - {false, -216, - MType({0xeb04ee2cfc701a37, 0xc5b134a5bb25cf2d, 0xd0761be212704b7f})}, - }, +// for i in range(-65, 65): +// r = 2^-28 * round( 2^28 / (1 + i*2^(-28)) ); +// s, m, e = RealField(128)(r).log10().sign_mantissa_exponent(); +// print("{false," if (s == -1) else "{true,", e, ", +// MType({", hex(m % 2^64), ",", hex((m >> 64) % 2^64), "})},"); +const Float128 LOG10_R4[130] = { + {true, -151, MType({0xe471a82bbedbe0ae, 0xe1d5464122cf95a4})}, + {true, -151, MType({0xaf6e93be8e4c1764, 0xde5bd6ec7f7bc110})}, + {true, -151, MType({0xe44848f0a5779499, 0xdae26797a490f80e})}, + {true, -151, MType({0x90205533f4e70566, 0xd768f842920f3a98})}, + {true, -151, MType({0xc01844ace3729e48, 0xd3ef88ed47f688a6})}, + {true, -151, MType({0x8151a2324e41c7c4, 0xd0761997c646e232})}, + {true, -151, MType({0xe0edf74d88cacafd, 0xccfcaa420d004734})}, + {true, -151, MType({0xec0ecc3a5cd27e58, 0xc9833aec1c22b7a6})}, + {true, -151, MType({0xafd5a7e70a6bf214, 0xc609cb95f3ae3381})}, + {true, -151, MType({0x39640ff447f81ceb, 0xc2905c3f93a2babe})}, + {true, -151, MType({0x95db88b5422588b1, 0xbf16ece8fc004d55})}, + {true, -151, MType({0xd25d952f9beffeec, 0xbb9d7d922cc6eb40})}, + {true, -151, MType({0xfc0bb71b6ea03578, 0xb8240e3b25f69478})}, + {true, -151, MType({0x20076ee349cb7b20, 0xb4aa9ee3e78f48f7})}, + {true, -151, MType({0x4b723ba43353643d, 0xb1312f8c719108b4})}, + {true, -151, MType({0x8b6d9b2da7657754, 0xadb7c034c3fbd3a9})}, + {true, -151, MType({0xed1b0a01987ad9b4, 0xaa3e50dcdecfa9cf})}, + {true, -151, MType({0x7d9c03546f57fc11, 0xa6c4e184c20c8b20})}, + {true, -151, MType({0x4a12010d0b0c4727, 0xa34b722c6db27794})}, + {true, -151, MType({0x5f9e7bc4c0f1c851, 0x9fd202d3e1c16f24})}, + {true, -151, MType({0xcb62eac75cacde29, 0x9c58937b1e3971c9})}, + {true, -151, MType({0x9a80c413202be52a, 0x98df2422231a7f7d})}, + {true, -151, MType({0xda197c58c3a6e445, 0x9565b4c8f0649838})}, + {true, -151, MType({0x974e86fb759f3988, 0x91ec456f8617bbf4})}, + {true, -151, MType({0xdf415610dadf46b3, 0x8e72d615e433eaa9})}, + {true, -151, MType({0xbf135a610e7a1ddc, 0x8af966bc0ab92451})}, + {true, -151, MType({0x43e60366a1cb2e09, 0x877ff761f9a768e5})}, + {true, -151, MType({0x7adabf4e9c75efce, 0x84068807b0feb85d})}, + {true, -151, MType({0x7112faf87c6591ee, 0x808d18ad30bf12b3})}, + {true, -152, MType({0x676043ec6b994be5, 0xfa2752a4f1d0efc0})}, + {true, -152, MType({0x9fa73d186649999d, 0xf33473ef12f5cfb9})}, + {true, -152, MType({0xa53db362aa5cc6f0, 0xec419538c4ecc544})}, + {true, -152, MType({0x9266761de5e05f13, 0xe54eb68207b5d053})}, + {true, -152, MType({0x81645201b36e17ba, 0xde5bd7cadb50f0d8})}, + {true, -152, MType({0x8c7a112a9a2b2a52, 0xd768f9133fbe26c5})}, + {true, -152, MType({0xcdea7b1a0dc7ad42, 0xd0761a5b34fd720c})}, + {true, -152, MType({0x5ff854b66e7ded1f, 0xc9833ba2bb0ed2a0})}, + {true, -152, MType({0x5ce6604b0911c5ed, 0xc2905ce9d1f24872})}, + {true, -152, MType({0xdef75d8816cffc59, 0xbb9d7e3079a7d374})}, + {true, -152, MType({0x6e0982bd8d96ef, 0xb4aa9f76b22f739a})}, + {true, -152, MType({0xdb8d1eb50fa7375c, 0xadb7c0bc7b8928d3})}, + {true, -152, MType({0x8a9754fe0c0073a7, 0xa6c4e201d5b4f314})}, + {true, -152, MType({0x27cf61a19e032f69, 0x9fd20346c0b2d24e})}, + {true, -152, MType({0xcd77f7489d9ef50b, 0x98df248b3c82c672})}, + {true, -152, MType({0x95d3c600cf484f03, 0x91ec45cf4924cf74})}, + {true, -152, MType({0x9b257b3ce3f82109, 0x8af96712e698ed45})}, + {true, -152, MType({0xf7afc1d4792b015a, 0x8406885614df1fd7})}, + {true, -153, MType({0x8b6a840831c123d8, 0xfa275331a7eece3b})}, + {true, -153, MType({0x3ef142da7335b35a, 0xec4195b647c38612})}, + {true, -153, MType({0x3e79062c7cbb3b7d, 0xde5bd83a093c6718})}, + {true, -153, MType({0xbe870ed4ed5b755b, 0xd0761abcec597131})}, + {true, -153, MType({0xf3a098743d20fb64, 0xc2905d3ef11aa442})}, + {true, -153, MType({0x124ad974bd15fbca, 0xb4aa9fc017800030})}, + {true, -153, MType({0x4f0b030a9742eb00, 0xa6c4e2405f8984dd})}, + {true, -153, MType({0xde664133cead362d, 0x98df24bfc937322e})}, + {true, -153, MType({0xf4e1bab83f55f5a1, 0x8af9673e54890808})}, + {true, -154, MType({0x8e0522533c713e98, 0xfa27537802fe0c9f})}, + {true, -154, MType({0x129bc1c6f293726e, 0xde5bd871a03259cf})}, + {true, -154, MType({0xe09182166eeb17eb, 0xc2905d6980aef768})}, + {true, -154, MType({0x60f08720313daa3f, 0xa6c4e25fa473e535})}, + {true, -154, MType({0xfcc2ea566b3af38b, 0x8af967540b8122fc})}, + {true, -155, MType({0x3a25757e00f4e3a0, 0xde5bd88d6bad6110})}, + {true, -155, MType({0x55d3f9e70cf177b8, 0xa6c4e26f46e91b3e})}, + {true, -156, MType({0x3d4aac85125398d0, 0xde5bd89b516ae82a})}, + {true, -157, MType({0x9ab5a849a06f400d, 0xde5bd8a24449ac95})}, + {false, 0, MType({0x0, 0x0})}, + {false, -157, MType({0xd3cc88fd4ef34c2, 0xde5bd8b02a073729})}, + {false, -156, MType({0x225916c2b3f33c90, 0xde5bd8b71ce5fd51})}, + {false, -155, MType({0x17847f98acf08d54, 0xa6c4e28e8bd3930a})}, + {false, -155, MType({0x44397830931fddd, 0xde5bd8c502a38b5e})}, + {false, -154, MType({0xc2ab385913176984, 0x8af9677f79717409})}, + {false, -154, MType({0xe454dec82bde52e5, 0xa6c4e29e2e48d4cc})}, + {false, -154, MType({0xfe1522b0470d7d7f, 0xc2905dbe9fd7e82f})}, + {false, -154, MType({0xa6e2721f2afc3cce, 0xde5bd8e0ce1eae6a})}, + {false, -154, MType({0x75b3458eec3c106c, 0xfa275404b91d27b4})}, + {false, -153, MType({0x80bf0ff2f6cd9f93, 0x8af967953069aa22})}, + {false, -153, MType({0xf09cc73b7013b906, 0x98df2528e2a09a29})}, + {false, -153, MType({0x55ee1480619827c4, 0xa6c4e2bd7333640c})}, + {false, -153, MType({0x7c2e48d772250b3c, 0xb4aaa052e22207e5})}, + {false, -153, MType({0x2ed8ba8c6fa81c98, 0xc2905de92f6c85d1})}, + {false, -153, MType({0x3968c5214f33fc4f, 0xd0761b805b12ddeb})}, + {false, -153, MType({0x6759c94e2d017fad, 0xde5bd9186515104f})}, + {false, -153, MType({0x84272d014c70fe58, 0xec4196b14d731d19})}, + {false, -153, MType({0x5b4c5b5f180b9fe1, 0xfa27544b142d0465})}, + {false, -152, MType({0x5c22626110c254a4, 0x840688f2dca16327})}, + {false, -152, MType({0xb345ef5d90dd6545, 0x8af967c09e5a3178})}, + {false, -152, MType({0x98ce92087c5cb614, 0x91ec468ecf40ed34})}, + {false, -152, MType({0xf27a0a6056dcfe57, 0x98df255d6f559668})}, + {false, -152, MType({0xa6061afeb7929f24, 0x9fd2042c7e982d23})}, + {false, -152, MType({0x99308918494a4a20, 0xa6c4e2fbfd08b172})}, + {false, -152, MType({0xb1b71c7cca69a844, 0xadb7c1cbeaa72363})}, + {false, -152, MType({0xd5579f970cf000a9, 0xb4aaa09c47738304})}, + {false, -152, MType({0xe9cfdf6cf676df42, 0xbb9d7f6d136dd063})}, + {false, -152, MType({0xd4ddab9f8032bbab, 0xc2905e3e4e960b8e})}, + {false, -152, MType({0x7c3ed66ab6f39fe9, 0xc9833d0ff8ec3493})}, + {false, -152, MType({0xc5b134a5bb25cf2e, 0xd0761be212704b7f})}, + {false, -152, MType({0x96f29dc2c0d26ca0, 0xd768fab49b225061})}, + {false, -152, MType({0xd5c0ebcf0fa0221e, 0xde5bd98793024346})}, + {false, -152, MType({0x67d9fb7302d3c705, 0xe54eb85afa10243d})}, + {false, -152, MType({0x32fbabf2095106f1, 0xec41972ed04bf353})}, + {false, -152, MType({0x1ce3df2aa59b0889, 0xf334760315b5b096})}, + {false, -152, MType({0xb5079966dd5143e, 0xfa2754d7ca4d5c14})}, + {false, -151, MType({0x71ffb12505e19d89, 0x808d19d677097aed})}, + {false, -151, MType({0x4657417a9e657eae, 0x8406894140833efc})}, + {false, -151, MType({0x758de3f168f9f8c9, 0x877ff8ac4193fa3d})}, + {false, -151, MType({0xf2828ffc57f43581, 0x8af968177a3bacb7})}, + {false, -151, MType({0xb0143e5be77b1053, 0x8e72d782ea7a5672})}, + {false, -151, MType({0xa121e91e1d8769ef, 0x91ec46ee924ff774})}, + {false, -151, MType({0xb88a8b9e89e47b9c, 0x9565b65a71bc8fc4})}, + {false, -151, MType({0xe92d228646302a9c, 0x98df25c688c01f69})}, + {false, -151, MType({0x25e8abcbf5db5b8c, 0x9c589532d75aa66b})}, + {false, -151, MType({0x619c26b3c62a45c8, 0x9fd2049f5d8c24cf})}, + {false, -151, MType({0x8f2693cf6e34c6cc, 0xa34b740c1b549a9d})}, + {false, -151, MType({0xa166f4fe2ee6b59a, 0xa6c4e37910b407dc})}, + {false, -151, MType({0x8b3c4d6cd3003616, 0xaa3e52e63daa6c93})}, + {false, -151, MType({0x3f85a195af160c71, 0xadb7c253a237c8c9})}, + {false, -151, MType({0xb121f740a191f084, 0xb13131c13e5c1c84})}, + {false, -151, MType({0xd2f0558312b2e136, 0xb4aaa12f121767cc})}, + {false, -151, MType({0x97cfc4bff48d77de, 0xb824109d1d69aaa8})}, + {false, -151, MType({0xf29f4ea7c30c3ba5, 0xbb9d800b6052e51e})}, + {false, -151, MType({0xd63dfe3883eff4e9, 0xbf16ef79dad31736})}, + {false, -151, MType({0x358adfbdc6d0009f, 0xc2905ee88cea40f7})}, + {false, -151, MType({0x36500d0a51aa3b6, 0xc609ce5776986267})}, + {false, -151, MType({0x32ab7057c2155e78, 0xc9833dc697dd7b8d})}, + {false, -151, MType({0xb63d3e874add3ff0, 0xccfcad35f0b98c70})}, + {false, -151, MType({0x80f97ce0f6673948, 0xd0761ca5812c9518})}, + {false, -151, MType({0x85bf3e340580712d, 0xd3ef8c154936958b})}, + {false, -151, MType({0xb76d969d42ce9734, 0xd768fb8548d78dd0})}, + {false, -151, MType({0x8e39b8702d0373a, 0xdae26af5800f7def})}, + {false, -151, MType({0x6d0063a923dd0cc6, 0xde5bda65eede65ed})}, }; -// > P = fpminimax(log10(1 + x)/x, 4, [|192...|], [-2^-27, 2^-27]); +// > P = fpminimax(log10(1 + x)/x, 3, [|128...|], [-0x1.0002143p-29 , 0x1p-29]); // > P; -// > dirtyinfnorm(log10(1 + x)/x - P, [-2^-27, 2^-27]); -// 0x1.287a7...p-143 -const Float192 BIG_COEFFS[5]{ - {false, -194, - MType({0x1fc14ee0c0158d73, 0x762ec7601912bf70, 0x58f189dd49436234})}, - {true, -195, - MType({0x8f42a80e947f6357, 0x67836140b941fe04, 0xde5bd8a93728747a})}, - {false, -194, - MType({0xf6f00690b1fa8ba9, 0x78e7c71fc8ca2d3a, 0x943d3b1b7a1af663})}, - {true, -191, - MType({0x255a69358264a2d1, 0xa6ab7555f5a64d33, 0x1bcb7b1526e50e32})}, - {false, -193, - MType({0x3ee3460246fdf301, 0x355baaafad33dc32, 0xde5bd8a937287195})}, +// > dirtyinfnorm(log10(1 + x)/x - P, [-0x1.0002143p-29 , 0x1p-29]); +// 0x1.64fb8...p-123 +const Float128 BIG_COEFFS[4]{ + {true, -131, MType({0x6903c4ce1582517d, 0xde5bd8a9373f89a7})}, + {false, -130, MType({0xb8a21791624e2e8a, 0x943d3b1b7a1af679})}, + {true, -130, MType({0x355baaafabc25990, 0xde5bd8a937287195})}, + {false, -129, MType({0x355baaafad33dbd9, 0xde5bd8a937287195})}, }; // Reuse the output of the fast pass range reduction. -// |m_x| < 2^-7 +// -2^-8 <= m_x < 2^-7 double log10_accurate(int e_x, int index, double m_x) { - Float192 e_x_f192(static_cast(e_x)); - Float192 sum = fputil::quick_add(LOG10_R_F192[index], - fputil::quick_mul(LOG10_2, e_x_f192)); - fputil::DoubleDouble mx{/*lo*/ 0.0, /*hi*/ m_x}; - - // Further range reductions. - double scale = 0x1.0p+7; - for (size_t i = 0; i < R_STEPS; ++i) { - scale *= 0x1.0p+4; - int id = static_cast(fputil::multiply_add(mx.hi, scale, 0x1.0p+4)); - double r = RR[i][id]; - fputil::DoubleDouble rm = fputil::exact_mult(r, mx.hi); - rm.hi += r - 1.0; - rm.lo = fputil::multiply_add(r, mx.lo, rm.lo); - mx = fputil::exact_add(rm.hi, rm.lo); - sum = fputil::quick_add(sum, LOG10_RR[i][id]); - } - // Now |m_x| <= 2^-27 - Float192 m_hi(mx.hi); - Float192 m_lo(mx.lo); - Float192 m = fputil::quick_add(m_hi, m_lo); - Float192 p = fputil::quick_mul(m, BIG_COEFFS[0]); - - for (size_t i = 1; i < 5; ++i) { - auto aa = fputil::quick_add(p, BIG_COEFFS[i]); - p = fputil::quick_mul(m, aa); - }; - - return static_cast(fputil::quick_add(sum, p)); + Float128 e_x_f128(static_cast(e_x)); + Float128 sum = fputil::quick_mul(LOG10_2, e_x_f128); + + sum = fputil::quick_add(sum, LOG10_R1[index]); + + int64_t v = static_cast(m_x * 0x1.0p60); // ulp = 2^-60 + + // Range reduction - Step 2 + // Output range: vv2 in [-0x1.3ffcp-15, 0x1.3e3dp-15]. + // idx2 = trunc(2^14 * (v + 2^-8 + 2^-15)) + size_t idx2 = static_cast((v + 0x10'2000'0000'0000) >> 46); + sum = fputil::quick_add(sum, LOG10_R2[idx2]); + + int64_t s2 = S2[idx2]; // |s| <= 2^-7, ulp = 2^-16 + int64_t sv2 = s2 * v; // |s*v| < 2^-14, ulp = 2^(-60-16) = 2^-76 + int64_t spv2 = (s2 << 44) + v; // |s + v| < 2^-14, ulp = 2^-60 + int64_t vv2 = (spv2 << 16) + sv2; // |vv2| < 2^-14, ulp = 2^-76 + + // Range reduction - Step 3 + // Output range: vv3 in [-0x1.01928p-22 , 0x1p-22] + // idx3 = trunc(2^21 * (v + 80*2^-21 + 2^-22)) + size_t idx3 = static_cast((vv2 + 0x2840'0000'0000'0000) >> 55); + sum = fputil::quick_add(sum, LOG10_R3[idx3]); + + int64_t s3 = S3[idx3]; // |s| < 2^-13, ulp = 2^-21 + int64_t spv3 = (s3 << 55) + vv2; // |s + v| < 2^-21, ulp = 2^-76 + // |s*v| < 2^-27, ulp = 2^(-76-21) = 2^-97 + __int128_t sv3 = static_cast<__int128_t>(s3) * static_cast<__int128_t>(vv2); + // |vv3| < 2^-21, ulp = 2^-97 + __int128_t vv3 = (static_cast<__int128_t>(spv3) << 21) + sv3; + + // Range reduction - Step 4 + // Output range: vv4 in [-0x1.0002143p-29 , 0x1p-29] + // idx4 = trunc(2^21 * (v + 65*2^-28 + 2^-29)) + size_t idx4 = static_cast((static_cast(vv3 >> 68) + 131) >> 1); + + sum = fputil::quick_add(sum, LOG10_R4[idx4]); + + __int128_t s4 = static_cast<__int128_t>(S4[idx4]); // |s| < 2^-21, ulp = 2^-28 + // |s + v| < 2^-28, ulp = 2^-97 + __int128_t spv4 = (s4 << 69) + vv3; + // |s*v| < 2^-42, ulp = 2^(-97-28) = 2^-125 + __int128_t sv4 = s4 * vv3; + // |vv4| < 2^-28, ulp = 2^-125 + __int128_t vv4 = (spv4 << 28) + sv4; + + Float128 v_f128 = vv4 < 0 + ? Float128(true, -125, + MType({static_cast(-vv4), + static_cast((-vv4) >> 64)})) + : Float128(false, -125, + MType({static_cast(vv4), + static_cast(vv4 >> 64)})); + + // Polynomial approximation + Float128 p = fputil::quick_mul(v_f128, BIG_COEFFS[0]); + p = fputil::quick_mul(v_f128, fputil::quick_add(p, BIG_COEFFS[1])); + p = fputil::quick_mul(v_f128, fputil::quick_add(p, BIG_COEFFS[2])); + p = fputil::quick_mul(v_f128, fputil::quick_add(p, BIG_COEFFS[3])); + + Float128 r = fputil::quick_add(sum, p); + + return static_cast(r); } } // namespace -// TODO(lntue): Make the implementation correctly rounded for non-FMA targets. LLVM_LIBC_FUNCTION(double, log10, (double x)) { using FPBits_t = typename fputil::FPBits; FPBits_t xbits(x); - int x_e = -1023; + uint64_t x_u = xbits.uintval(); + + int x_e = -FPBits_t::EXPONENT_BIAS; + + if (LIBC_UNLIKELY(x_u == 0x3FF0'0000'0000'0000ULL)) { + // log10(1.0) = +0.0 + return 0.0; + } if (LIBC_UNLIKELY(xbits.uintval() < FPBits_t::MIN_NORMAL || xbits.uintval() > FPBits_t::MAX_NORMAL)) { @@ -968,117 +881,132 @@ // Normalize denormal inputs. xbits.set_val(x * 0x1.0p52); x_e -= 52; + x_u = xbits.uintval(); } // log10(x) = log10(2^x_e * x_m) // = x_e * log10(2) + log10(x_m) // Range reduction for log10(x_m): - // For each x_m, we would like to find R such that: - // |R * x_m - 1| < C - uint64_t x_u = xbits.uintval(); + // For each x_m, we would like to find r such that: + // -2^-8 <= r * x_m - 1 < 2^-7 int shifted = x_u >> 45; int index = shifted & 0x7F; - double r = R[index]; + double r = RD[index]; - x_e += (x_u >> 52) & 0x7FF; + // Add unbiased exponent. Add an extra 1 if the 8 leading fractional bits are + // all 1's. + x_e += static_cast((x_u + (1ULL << 45)) >> 52); double e_x = static_cast(x_e); - int e_err = (e_x == -1) && (index == 0x7F); - int logr_err = (index == 0); - - double err = - fputil::multiply_add(e_x, LOG10_2_ULP[e_err], LOG10_R_ULP[logr_err]); - // hi is exact - double hi = fputil::multiply_add(e_x, LOG10_2_HI, LOG10_R[index].hi); - // lo errors ~ e_x * LSB(LOG10_2_LO) + LSB(LOG10_R[index].lo) + rounding err - // <= 2 * (e_x * LSB(LOG10_2_LO) + LSB(LOG10_R[index].lo)) - double lo = fputil::multiply_add(e_x, LOG10_2_LO, LOG10_R[index].lo); - // A bound on the error is given - // in "Note on FastTwoSum with Directed Roundings" - // by Paul Zimmermann, https://hal.inria.fr/hal-03798376, 2022. - // Theorem 1 says that - // the difference between a+b and hi+lo is bounded by 2u^2|a+b| - // and also by 2u^2|hi|. Here u=2^-53, thus we get: - // |(a+b)-(hi+lo)| <= 2^-105 min(|a+b|,|hi|) - // So the overall errors <= 2^-105 min(|a+b|, |hi|) + 2*(...) - fputil::DoubleDouble rr = fputil::exact_add(hi, lo); + double hi = fputil::multiply_add(e_x, LOG_2_HI, LOG_R_DD[index].hi); + // lo errors ~ e_x * LSB(LOG_2_LO) + LSB(LOG_R[index].lo) + rounding err + // <= 2 * (e_x * LSB(LOG_2_LO) + LSB(LOG_R[index].lo)) + double lo = fputil::multiply_add(e_x, LOG_2_LO, LOG_R_DD[index].lo); + // Set m = 1.mantissa. uint64_t x_m = (x_u & 0x000F'FFFF'FFFF'FFFFULL) | 0x3FF0'0000'0000'0000ULL; double m = FPBits_t(x_m).get_val(); - double u = fputil::multiply_add(r, m, -1.0); // exact - err = fputil::multiply_add(u, P_ERR, err); + double u, u_sq, err; + fputil::DoubleDouble r1; + + // Perform exact range reduction +#ifdef LIBC_TARGET_CPU_HAS_FMA + u = fputil::multiply_add(r, m, -1.0); // exact +#else + uint64_t c_m = x_m & 0x3FFF'E000'0000'0000ULL; + double c = FPBits_t(c_m).get_val(); + u = fputil::multiply_add(r, m - c, CD[index]); // exact +#endif // LIBC_TARGET_CPU_HAS_FMA + // Error of u_sq = ulp(u^2); + u_sq = u * u; // Degree-7 minimax polynomial - double u_sq = u * u; - double p0 = u * COEFFS[0]; - double p1 = fputil::multiply_add(u, COEFFS[2], COEFFS[1]); - double p2 = fputil::multiply_add(u, COEFFS[4], COEFFS[3]); - double p3 = fputil::multiply_add(u, COEFFS[6], COEFFS[5]); - double p01 = fputil::multiply_add(u_sq, p1, p0); - double p23 = fputil::multiply_add(u_sq, p3, p2); - double u4 = u_sq * u_sq; - fputil::DoubleDouble re = fputil::exact_add(rr.hi, p01); - double ll = fputil::multiply_add(u4, p23, re.lo + rr.lo); + double p0 = fputil::multiply_add(u, LOG_COEFFS[1], LOG_COEFFS[0]); + double p1 = fputil::multiply_add(u, LOG_COEFFS[3], LOG_COEFFS[2]); + double p2 = fputil::multiply_add(u, LOG_COEFFS[5], LOG_COEFFS[4]); + double p = fputil::polyeval(u_sq, lo, p0, p1, p2); + + // Exact sum: + // r1.hi + r1.lo = e_x * log(2)_hi - log(r)_hi + u + r1 = fputil::exact_add(hi, u); + r1.lo += p; + + // Quick double-double multiplication: + // r2.hi + r2.lo ~ r1 * log10(e), + // with error bounded by: + // 4*ulp( ulp(r2.hi) ) + fputil::DoubleDouble r2 = fputil::quick_mult(r1, LOG10_E); + + // Technicallly error of r1.lo is bounded by: + // |hi|*ulp(log(2)_lo) + C*ulp(u^2) + // To simplify the error computation a bit, we replace |hi|*ulp(log(2)_lo) + // with the upper bound: 2^11 * ulp(log(2)_lo) = 2^-85. + // Total error is bounded by ~ C * ulp(u^2). + err = fputil::multiply_add(u_sq, P_ERR, HI_ERR); + // Lower bound from the result - double left = re.hi + (ll - err); + double left = r2.hi + (r2.lo - err); // Upper bound from the result - double right = re.hi + (ll + err); + double right = r2.hi + (r2.lo + err); // Ziv's test if fast pass is accurate enough. if (left == right) return left; // Exact cases: - switch (x_u) { - case 0x3ff0000000000000: // x = 1.0 - return 0.0; - case 0x4024000000000000: // x = 10.0 - return 1.0; - case 0x4059000000000000: // x = 10^2 - return 2.0; - case 0x408f400000000000: // x = 10^3 - return 3.0; - case 0x40c3880000000000: // x = 10^4 - return 4.0; - case 0x40f86a0000000000: // x = 10^5 - return 5.0; - case 0x412e848000000000: // x = 10^6 - return 6.0; - case 0x416312d000000000: // x = 10^7 - return 7.0; - case 0x4197d78400000000: // x = 10^8 - return 8.0; - case 0x41cdcd6500000000: // x = 10^9 - return 9.0; - case 0x4202a05f20000000: // x = 10^10 - return 10.0; - case 0x42374876e8000000: // x = 10^11 - return 11.0; - case 0x426d1a94a2000000: // x = 10^12 - return 12.0; - case 0x42a2309ce5400000: // x = 10^13 - return 13.0; - case 0x42d6bcc41e900000: // x = 10^14 - return 14.0; - case 0x430c6bf526340000: // x = 10^15 - return 15.0; - case 0x4341c37937e08000: // x = 10^16 - return 16.0; - case 0x4376345785d8a000: // x = 10^17 - return 17.0; - case 0x43abc16d674ec800: // x = 10^18 - return 18.0; - case 0x43e158e460913d00: // x = 10^19 - return 19.0; - case 0x4415af1d78b58c40: // x = 10^20 - return 20.0; - case 0x444b1ae4d6e2ef50: // x = 10^21 - return 21.0; - case 0x4480f0cf064dd592: // x = 10^22 - return 22.0; + if (LIBC_UNLIKELY((x_u & 0x3FFFFF) == 0)) { + switch (x_u) { + case 0x4024000000000000: // x = 10.0 + return 1.0; + case 0x4059000000000000: // x = 10^2 + return 2.0; + case 0x408f400000000000: // x = 10^3 + return 3.0; + case 0x40c3880000000000: // x = 10^4 + return 4.0; + case 0x40f86a0000000000: // x = 10^5 + return 5.0; + case 0x412e848000000000: // x = 10^6 + return 6.0; + case 0x416312d000000000: // x = 10^7 + return 7.0; + case 0x4197d78400000000: // x = 10^8 + return 8.0; + case 0x41cdcd6500000000: // x = 10^9 + return 9.0; + case 0x4202a05f20000000: // x = 10^10 + return 10.0; + case 0x42374876e8000000: // x = 10^11 + return 11.0; + case 0x426d1a94a2000000: // x = 10^12 + return 12.0; + case 0x42a2309ce5400000: // x = 10^13 + return 13.0; + } + } else { + switch (x_u) { + case 0x42d6bcc41e900000: // x = 10^14 + return 14.0; + case 0x430c6bf526340000: // x = 10^15 + return 15.0; + case 0x4341c37937e08000: // x = 10^16 + return 16.0; + case 0x4376345785d8a000: // x = 10^17 + return 17.0; + case 0x43abc16d674ec800: // x = 10^18 + return 18.0; + case 0x43e158e460913d00: // x = 10^19 + return 19.0; + case 0x4415af1d78b58c40: // x = 10^20 + return 20.0; + case 0x444b1ae4d6e2ef50: // x = 10^21 + return 21.0; + case 0x4480f0cf064dd592: // x = 10^22 + return 22.0; + } } return log10_accurate(x_e, index, u); diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt --- a/libc/test/src/math/CMakeLists.txt +++ b/libc/test/src/math/CMakeLists.txt @@ -1307,8 +1307,6 @@ libc.include.math libc.src.math.log10 libc.src.__support.FPUtil.fp_bits - FLAGS - FMA_OPT__ONLY ) add_fp_unittest( diff --git a/libc/test/src/math/log10_test.cpp b/libc/test/src/math/log10_test.cpp --- a/libc/test/src/math/log10_test.cpp +++ b/libc/test/src/math/log10_test.cpp @@ -18,21 +18,22 @@ #include namespace mpfr = __llvm_libc::testing::mpfr; +using __llvm_libc::testing::tlog; DECLARE_SPECIAL_CONSTANTS(double) TEST(LlvmLibcLog10Test, SpecialNumbers) { EXPECT_FP_EQ(aNaN, __llvm_libc::log10(aNaN)); EXPECT_FP_EQ(inf, __llvm_libc::log10(inf)); - EXPECT_TRUE(FPBits(__llvm_libc::log10(neg_inf)).is_nan()); - EXPECT_FP_EQ(neg_inf, __llvm_libc::log10(0.0)); - EXPECT_FP_EQ(neg_inf, __llvm_libc::log10(-0.0)); - EXPECT_TRUE(FPBits(__llvm_libc::log10(-1.0)).is_nan()); - EXPECT_FP_EQ(zero, __llvm_libc::log10(1.0)); + EXPECT_FP_IS_NAN_WITH_EXCEPTION(__llvm_libc::log10(neg_inf), FE_INVALID); + EXPECT_FP_EQ_WITH_EXCEPTION(neg_inf, __llvm_libc::log10(0.0), FE_DIVBYZERO); + EXPECT_FP_EQ_WITH_EXCEPTION(neg_inf, __llvm_libc::log10(-0.0), FE_DIVBYZERO); + EXPECT_FP_IS_NAN_WITH_EXCEPTION(__llvm_libc::log10(-1.0), FE_INVALID); + EXPECT_FP_EQ_ALL_ROUNDING(zero, __llvm_libc::log10(1.0)); } TEST(LlvmLibcLog10Test, TrickyInputs) { - constexpr int N = 27; + constexpr int N = 35; constexpr uint64_t INPUTS[N] = { 0x3ff0000000000000, // x = 1.0 0x4024000000000000, // x = 10.0 @@ -57,9 +58,10 @@ 0x4415af1d78b58c40, // x = 10^20 0x444b1ae4d6e2ef50, // x = 10^21 0x4480f0cf064dd592, // x = 10^22 - 0x3fefffffffef06ad, 0x3fefde0f22c7d0eb, - 0x225e7812faadb32f, 0x3fee1076964c2903, - }; + 0x3fefffffffef06ad, 0x3fefde0f22c7d0eb, 0x225e7812faadb32f, + 0x3fee1076964c2903, 0x3fdfe93fff7fceb0, 0x3ff012631ad8df10, + 0x3fefbfdaa448ed98, 0x44b0c9705a25ce02, 0x2c88d301065c7f9b, + 0x30160580e7268a99, 0x5ca04103b7eaa345, 0x19ad77dc4a40093f}; for (int i = 0; i < N; ++i) { double x = double(FPBits(INPUTS[i])); EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Log10, x, @@ -67,9 +69,21 @@ } } +TEST(LlvmLibcLog10Test, AllExponents) { + double x = 0x1.0p-1074; + for (int i = -1074; i < 1024; ++i, x *= 2.0) { + ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Log10, x, + __llvm_libc::log10(x), 0.5); + } +} + TEST(LlvmLibcLog10Test, InDoubleRange) { constexpr uint64_t COUNT = 1234561; - constexpr uint64_t STEP = 0x3FF0'0000'0000'0000ULL / COUNT; + constexpr uint64_t START = 0x3FD0'0000'0000'0000ULL; // 0.25 + constexpr uint64_t STOP = 0x4010'0000'0000'0000ULL; // 4.0 + // constexpr uint64_t START = 0x3FF0'0000'0000'0000ULL; // 1.0 + // constexpr uint64_t STOP = 0x4000'0000'0000'0000ULL; // 2.0 + constexpr uint64_t STEP = (STOP - START) / COUNT; auto test = [&](mpfr::RoundingMode rounding_mode) { mpfr::ForceRoundingMode __r(rounding_mode); @@ -79,14 +93,14 @@ double mx, mr = 0.0; double tol = 0.5; - for (uint64_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) { + for (uint64_t i = 0, v = START; i <= COUNT; ++i, v += STEP) { double x = FPBits(v).get_val(); if (isnan(x) || isinf(x) || x < 0.0) continue; libc_errno = 0; double result = __llvm_libc::log10(x); ++cc; - if (isnan(result)) + if (isnan(result) || isinf(result)) continue; ++count; @@ -102,16 +116,23 @@ } } } + tlog << " Log10 failed: " << fails << "/" << count << "/" << cc + << " tests.\n"; + tlog << " Max ULPs is at most: " << static_cast(tol) << ".\n"; if (fails) { EXPECT_MPFR_MATCH(mpfr::Operation::Log10, mx, mr, 0.5, rounding_mode); } }; + tlog << " Test Rounding To Nearest...\n"; test(mpfr::RoundingMode::Nearest); + tlog << " Test Rounding Downward...\n"; test(mpfr::RoundingMode::Downward); + tlog << " Test Rounding Upward...\n"; test(mpfr::RoundingMode::Upward); + tlog << " Test Rounding Toward Zero...\n"; test(mpfr::RoundingMode::TowardZero); } diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel --- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel @@ -955,6 +955,7 @@ srcs = ["src/math/generic/common_constants.cpp"], hdrs = ["src/math/generic/common_constants.h"], deps = [ + ":__support_number_pair", ":libc_root", ], )