25#ifndef __DCONV_SCHUBFACH_HPP__
26#define __DCONV_SCHUBFACH_HPP__
48 return (q * 315653 - (asymmetric ? 131008 : 0)) >> 20;
58 return (k * 3483294) >> 20;
69 uint64_t middle, unused;
75 const uint64_t z = low + middle;
77 return high | (z != 0);
86 inline uint64_t
shortest (
double value,
int& k)
noexcept
89 memcpy (&bits, &value,
sizeof (
double));
91 const uint64_t fraction = bits & 0x000FFFFFFFFFFFFF;
92 const int biased =
static_cast<int> (bits >> 52);
93 const uint64_t c = (biased != 0) ? (fraction | 0x0010000000000000) : fraction;
94 const int q = (biased != 0) ? biased - 1075 : -1074;
96 if ((
static_cast<unsigned> (-q) <= 52) && ((c & ((
static_cast<uint64_t
> (1) << -q) - 1)) == 0))
102 const bool asymmetric = (fraction == 0) && (biased > 1);
103 const uint64_t out = c & 1;
105 const uint64_t cb = c << 2;
106 const uint64_t cbl = asymmetric ? cb - 1 : cb - 2;
107 const uint64_t cbr = cb + 2;
114 const uint64_t vbl =
roundToOdd (g, cbl << h);
115 const uint64_t vbr =
roundToOdd (g, cbr << h);
117 const uint64_t s = vb >> 2;
118 const uint64_t sp10 = (s / 10) * 10;
119 const uint64_t tp10 = sp10 + 10;
120 const bool upin = vbl + out <= (sp10 << 2);
121 const bool wpin = (tp10 << 2) + out <= vbr;
124 uint64_t digits = upin ? s / 10 : s / 10 + 1;
126 if (digits < 1000000000000000)
134 const uint64_t t = s + 1;
135 const bool uin = vbl + out <= (s << 2);
136 const bool win = (t << 2) + out <= vbr;
142 const int64_t cmp =
static_cast<int64_t
> (vb - ((s + t) << 1));
143 return ((cmp < 0) || ((cmp == 0) && ((s & 1) == 0))) ? s : t;
153 inline void generate (
char* buffer,
int& length,
int& k,
double value)
noexcept
155 const uint64_t digits =
shortest (value, k);
168 inline char*
dtoa (
char* buffer,
double value)
noexcept
171 memcpy (&bits, &value,
sizeof (
double));
172 bool is_negative = (bits >> 63) != 0;
175 buffer += is_negative;
176 value = is_negative ? -value : value;
180 memcpy (buffer,
"0.0", 3);
185 const uint64_t digits =
shortest (value, k);
int countDigits(uint64_t digits) noexcept
count the digits of a decimal significand.
Definition digits.hpp:64
char * format(char *buffer, uint64_t digits, int length, int k) noexcept
write a decimal significand with the same layout as prettify.
Definition format.hpp:143
constexpr Power schubfachpow[]
Definition schubfachpow.hpp:35
void umul128(uint64_t a, uint64_t b, uint64_t &high, uint64_t &low) noexcept
multiply two 64 bits unsigned integers.
Definition power.hpp:52
int writeDigits(char *buffer, uint64_t digits, int length) noexcept
write the digits of a decimal significand.
Definition digits.hpp:108
constexpr int floorLog2Pow10(int k) noexcept
compute floor (log2 (10^k)).
Definition schubfach.hpp:56
char * dtoa(char *buffer, double value) noexcept
double to string conversion using Schubfach.
Definition schubfach.hpp:168
uint64_t shortest(double value, int &k) noexcept
compute the shortest decimal significand.
Definition schubfach.hpp:86
void generate(char *buffer, int &length, int &k, double value) noexcept
write the shortest decimal digits.
Definition schubfach.hpp:153
constexpr int floorLog10Pow2(int q, bool asymmetric) noexcept
compute floor (log10 (2^q)) or floor (log10 (3/4 * 2^q)).
Definition schubfach.hpp:46
uint64_t roundToOdd(const details::Power &g, uint64_t cp) noexcept
multiply by a power of ten and round to odd.
Definition schubfach.hpp:67
128 bits power.
Definition power.hpp:37