25#ifndef __DCONV_GRISU3_HPP__
26#define __DCONV_GRISU3_HPP__
52 inline bool roundWeed (
char* buffer,
int length, uint64_t wpW, uint64_t delta, uint64_t rest, uint64_t tenKappa,
53 uint64_t ulp)
noexcept
55 const uint64_t wpWup = wpW - ulp;
56 const uint64_t wpWdown = wpW + ulp;
58 while ((rest < wpWup) && (delta - rest >= tenKappa) &&
59 ((rest + tenKappa < wpWup) || (wpWup - rest >= rest + tenKappa - wpWup)))
65 if ((rest < wpWdown) && (delta - rest >= tenKappa) &&
66 ((rest + tenKappa < wpWdown) || (wpWdown - rest > rest + tenKappa - wpWdown)))
71 return (2 * ulp <= rest) && (rest <= delta - 4 * ulp);
88 const uint64_t tooLow = low._mantissa - unit;
89 const uint64_t tooHigh = high._mantissa + unit;
90 uint64_t unsafe = tooHigh - tooLow;
92 const DiyFp one (
static_cast<uint64_t
> (1) << -w._exponent, w._exponent);
93 uint32_t p1 =
static_cast<uint32_t
> (tooHigh >> -one.
_exponent);
94 uint64_t p2 = tooHigh & (one.
_mantissa - 1);
100 buffer[length++] =
static_cast<char> (
'0' + p1 /
details::pow10[kappa - 1]);
104 const uint64_t rest = (
static_cast<uint64_t
> (p1) << -one.
_exponent) + p2;
108 return roundWeed (buffer, length, tooHigh - w._mantissa, unsafe, rest,
118 buffer[length++] =
static_cast<char> (
'0' + (p2 >> -one.
_exponent));
125 return roundWeed (buffer, length, (tooHigh - w._mantissa) * unit, unsafe, p2, one.
_mantissa, unit);
137 inline void fallback (
char* buffer,
int& length,
int& k,
double value)
noexcept
140 const char* end = std::to_chars (text, text +
sizeof (text), value, std::chars_format::scientific).ptr;
141 const char* cur = text;
144 for (; *cur !=
'e'; ++cur)
148 buffer[length++] = *cur;
153 std::from_chars (cur + 2, end, exponent);
154 k = ((cur[1] ==
'-') ? -exponent : exponent) - (length - 1);
164 inline void generate (
char* buffer,
int& length,
int& k,
double value)
noexcept
166 DiyFp w, minus, plus;
169 if (!
digitsGen (minus, w, plus, buffer, length, k))
171 fallback (buffer, length, k, value);
181 inline char*
dtoa (
char* buffer,
double value)
noexcept
hand made floating point.
Definition diyfp.hpp:41
uint64_t _mantissa
mantissa.
Definition diyfp.hpp:223
int _exponent
exponent.
Definition diyfp.hpp:226
constexpr uint32_t pow10[]
powers of ten that fit in 32 bits.
Definition digits.hpp:36
int countDigits(uint64_t digits) noexcept
count the digits of a decimal significand.
Definition digits.hpp:64
void scaledBoundaries(double value, DiyFp &w, DiyFp &minus, DiyFp &plus, int &k) noexcept
compute the scaled value and its scaled boundaries.
Definition grisu2.hpp:47
bool digitsGen(const DiyFp &low, const DiyFp &w, const DiyFp &high, char *buffer, int &length, int &k) noexcept
generate the shortest digits within the liberal boundaries.
Definition grisu3.hpp:84
void fallback(char *buffer, int &length, int &k, double value) noexcept
write the shortest and closest decimal digits using the standard library.
Definition grisu3.hpp:137
char * dtoa(char *buffer, double value) noexcept
double to string conversion using Grisu3.
Definition grisu3.hpp:181
bool roundWeed(char *buffer, int length, uint64_t wpW, uint64_t delta, uint64_t rest, uint64_t tenKappa, uint64_t ulp) noexcept
round the last digit to the closest value and check it is safe.
Definition grisu3.hpp:52
void generate(char *buffer, int &length, int &k, double value) noexcept
write the shortest and closest decimal digits.
Definition grisu3.hpp:164
char * dtoa(char *buffer, double value, void(*generate)(char *, int &, int &, double) noexcept) noexcept
double to string conversion with the given digits generator.
Definition grisu.hpp:50