4 #include "util/math/float2decimal.h"     5 #include "base/logging.h"     7 #define FAST_DTOA_UNREACHABLE() __builtin_unreachable();    90 constexpr 
int const kAlpha = -60;
    91 constexpr 
int const kGamma = -32;
   147 CachedPower GetCachedPowerForBinaryExponent(
int e) {
   151   static constexpr CachedPower 
const kCachedPowers[] = {
   152       {0xAB70FE17C79AC6CA, -1060, -300},  
   153       {0xFF77B1FCBEBCDC4F, -1034, -292}, {0xBE5691EF416BD60C, -1007, -284},
   154       {0x8DD01FAD907FFC3C, -980, -276},  {0xD3515C2831559A83, -954, -268},
   155       {0x9D71AC8FADA6C9B5, -927, -260},  {0xEA9C227723EE8BCB, -901, -252},
   156       {0xAECC49914078536D, -874, -244},  {0x823C12795DB6CE57, -847, -236},
   157       {0xC21094364DFB5637, -821, -228},  {0x9096EA6F3848984F, -794, -220},
   158       {0xD77485CB25823AC7, -768, -212},  {0xA086CFCD97BF97F4, -741, -204},
   159       {0xEF340A98172AACE5, -715, -196},  {0xB23867FB2A35B28E, -688, -188},
   160       {0x84C8D4DFD2C63F3B, -661, -180},  {0xC5DD44271AD3CDBA, -635, -172},
   161       {0x936B9FCEBB25C996, -608, -164},  {0xDBAC6C247D62A584, -582, -156},
   162       {0xA3AB66580D5FDAF6, -555, -148},  {0xF3E2F893DEC3F126, -529, -140},
   163       {0xB5B5ADA8AAFF80B8, -502, -132},  {0x87625F056C7C4A8B, -475, -124},
   164       {0xC9BCFF6034C13053, -449, -116},  {0x964E858C91BA2655, -422, -108},
   165       {0xDFF9772470297EBD, -396, -100},  {0xA6DFBD9FB8E5B88F, -369, -92},
   166       {0xF8A95FCF88747D94, -343, -84},   {0xB94470938FA89BCF, -316, -76},
   167       {0x8A08F0F8BF0F156B, -289, -68},   {0xCDB02555653131B6, -263, -60},
   168       {0x993FE2C6D07B7FAC, -236, -52},   {0xE45C10C42A2B3B06, -210, -44},
   169       {0xAA242499697392D3, -183, -36},  
   170       {0xFD87B5F28300CA0E, -157, -28},  
   171       {0xBCE5086492111AEB, -130, -20},  
   172       {0x8CBCCC096F5088CC, -103, -12},  
   173       {0xD1B71758E219652C, -77, -4},    
   174       {0x9C40000000000000, -50, 4},     
   175       {0xE8D4A51000000000, -24, 12},    
   176       {0xAD78EBC5AC620000, 3, 20},      
   177       {0x813F3978F8940984, 30, 28},     
   178       {0xC097CE7BC90715B3, 56, 36},     
   179       {0x8F7E32CE7BEA5C70, 83, 44},     
   180       {0xD5D238A4ABE98068, 109, 52},     {0x9F4F2726179A2245, 136, 60},
   181       {0xED63A231D4C4FB27, 162, 68},     {0xB0DE65388CC8ADA8, 189, 76},
   182       {0x83C7088E1AAB65DB, 216, 84},     {0xC45D1DF942711D9A, 242, 92},
   183       {0x924D692CA61BE758, 269, 100},    {0xDA01EE641A708DEA, 295, 108},
   184       {0xA26DA3999AEF774A, 322, 116},    {0xF209787BB47D6B85, 348, 124},
   185       {0xB454E4A179DD1877, 375, 132},    {0x865B86925B9BC5C2, 402, 140},
   186       {0xC83553C5C8965D3D, 428, 148},    {0x952AB45CFA97A0B3, 455, 156},
   187       {0xDE469FBD99A05FE3, 481, 164},    {0xA59BC234DB398C25, 508, 172},
   188       {0xF6C69A72A3989F5C, 534, 180},    {0xB7DCBF5354E9BECE, 561, 188},
   189       {0x88FCF317F22241E2, 588, 196},    {0xCC20CE9BD35C78A5, 614, 204},
   190       {0x98165AF37B2153DF, 641, 212},    {0xE2A0B5DC971F303A, 667, 220},
   191       {0xA8D9D1535CE3B396, 694, 228},    {0xFB9B7CD9A4A7443C, 720, 236},
   192       {0xBB764C4CA7A44410, 747, 244},    {0x8BAB8EEFB6409C1A, 774, 252},
   193       {0xD01FEF10A657842C, 800, 260},    {0x9B10A4E5E9913129, 827, 268},
   194       {0xE7109BFBA19C0C9D, 853, 276},    {0xAC2820D9623BF429, 880, 284},
   195       {0x80444B5E7AA7CF85, 907, 292},    {0xBF21E44003ACDD2D, 933, 300},
   196       {0x8E679C2F5E44FF8F, 960, 308},    {0xD433179D9C8CB841, 986, 316},
   197       {0x9E19DB92B4E31BA9, 1013, 324},  
   200   constexpr 
int const kCachedPowersSize = 79;
   201   constexpr 
int const kCachedPowersMinDecExp = -300;
   211   int const f = kAlpha - e - 1;
   212   int const k = (f * 78913) / (1 << 18) + (f > 0);
   214   int const index = (-kCachedPowersMinDecExp + k + (8 - 1)) / 8;
   216   assert(index < kCachedPowersSize);
   217   static_cast<void>(kCachedPowersSize);  
   219   CachedPower 
const cached = kCachedPowers[index];
   220   assert(kAlpha <= cached.e + e + 64);
   221   assert(kGamma >= cached.e + e + 64);
   231 inline unsigned InitKappa(uint32_t n) {
   232   return base::CountDecimalDigit32(n);
   235 inline void Grisu2Round(
char& digit, uint64_t dist, uint64_t delta, uint64_t rest,
   239   assert(dist <= delta);
   240   assert(rest <= delta);
   261   while (rest < dist && delta - rest >= ten_k &&
   262          (rest + ten_k < dist || dist - rest > rest + ten_k - dist)) {
   263     DCHECK_NE(
'0', digit);
   269 void SetDigits(uint32_t value, 
unsigned num_digits, 
char* buffer) {
   270   const char DIGITS[] =
   271         "0001020304050607080910111213141516171819"   272         "2021222324252627282930313233343536373839"   273         "4041424344454647484950515253545556575859"   274         "6061626364656667686970717273747576777879"   275         "8081828384858687888990919293949596979899";
   277   buffer += num_digits;
   279   while (value >= 100) {
   283     unsigned index = static_cast<unsigned>((value % 100) * 2);
   285     *--buffer = DIGITS[index + 1];
   286     *--buffer = DIGITS[index];
   289     *--buffer = static_cast<char>(
'0' + value);
   292   unsigned index = static_cast<unsigned>(value * 2);
   293   *--buffer = DIGITS[index + 1];
   294   *--buffer = DIGITS[index];
   297 std::pair<unsigned, int> Grisu2DigitGen(
char* buffer, 
int decimal_exponent,
   298   const Fp& M_minus, 
const Fp& w, 
const Fp& M_plus) {
   299   static constexpr 
char const* 
const kDigits = 
"0123456789";
   301   static_assert(kAlpha >= -60, 
"invalid parameter");
   302   static_assert(kGamma <= -32, 
"invalid parameter");
   304   assert(M_plus.e >= kAlpha);
   305   assert(M_plus.e <= kGamma);
   307   uint64_t delta = M_plus.f - M_minus.f;        
   308   uint64_t dist = M_plus.f - w.f;  
   323   const uint64_t e_shift = -M_plus.e;
   324   const uint64_t e_mask = (1ULL << e_shift) - 1;
   326   uint32_t p1 = M_plus.f >> e_shift;
   327   uint64_t p2 = M_plus.f & e_mask;  
   336   unsigned kappa = InitKappa(p1);
   357   bool cut_early = delta >= p2;
   358   uint32_t length = kappa;
   361     uint32_t p1_remainder = 0;
   364     uint32_t delta_shifted = (delta - p2) >> e_shift;  
   365     bool check_increase_power = 
true;
   367     if (delta_shifted > 0) {
   368       power = base::CountDecimalDigit32(delta_shifted);
   369       ten_n = base::Power10(power);
   370       p1_remainder = p1 % ten_n;
   371       if (p1_remainder > delta_shifted) {
   374         p1_remainder %= ten_n;
   375         check_increase_power = 
false;
   377       DCHECK_LE(p1_remainder, delta_shifted);
   382     if (check_increase_power) {
   383       while (p1 % 10 == 0) {
   391     SetDigits(p1, length, buffer);
   396     decimal_exponent += power;
   412       uint64_t rest = (uint64_t(p1_remainder) << e_shift) + p2;
   413       uint64_t ten_n64 = uint64_t(ten_n) << e_shift;
   415       while (rest < dist && delta - rest >= ten_n64 &&
   416              ten_n64 / 2 < (dist - rest)) {
   417         DCHECK_NE(
'0', buffer[length-1]);
   423     return std::pair<unsigned, int>(length, decimal_exponent);
   426   SetDigits(p1, length, buffer);
   456   DCHECK_GT(p2, delta);
   464     DCHECK_LE(p2, e_mask);
   467     uint64_t 
const d = p2 >> e_shift;      
   468     uint64_t 
const r = p2 & e_mask;  
   477     buffer[length++] = kDigits[d];  
   493     uint64_t 
const rest = p2;
   497       decimal_exponent += m;
   513       uint64_t 
const ten_m = 1ULL << e_shift;
   514       Grisu2Round(buffer[length-1], dist, delta, rest, ten_m);
   515       return std::pair<unsigned, int>(length, decimal_exponent);
   538 std::pair<unsigned, int> Grisu2(Fp m_minus, Fp v, Fp m_plus, 
char* buf) {
   539   assert(v.e == m_minus.e);
   540   assert(v.e == m_plus.e);
   552   CachedPower 
const cached = GetCachedPowerForBinaryExponent(m_plus.e);
   554   Fp 
const c_minus_k(cached.f, cached.e);  
   556   Fp 
const w = v.Mul(c_minus_k);  
   557   Fp 
const w_minus = m_minus.Mul(c_minus_k);
   558   Fp 
const w_plus = m_plus.Mul(c_minus_k);
   583   Fp 
const M_minus = Fp(w_minus.f + 1, w_minus.e);
   584   Fp 
const M_plus = Fp(w_plus.f - 1, w_plus.e);
   586   return Grisu2DigitGen(buf, -cached.k, M_minus, w, M_plus);
   594 char* AppendExponent(
char* buf, 
int e) {
   595   static constexpr 
char const* 
const kDigits = 
"0123456789";
   596   static constexpr 
char const* 
const kDigits100 =
   597       "00010203040506070809"   598       "10111213141516171819"   599       "20212223242526272829"   600       "30313233343536373839"   601       "40414243444546474849"   602       "50515253545556575859"   603       "60616263646566676869"   604       "70717273747576777879"   605       "80818283848586878889"   606       "90919293949596979899";
   612     *buf++ = 
'-', e = -e;
   616   uint32_t 
const k = static_cast<uint32_t>(e);
   620   } 
else if (k < 100) {
   621     *buf++ = kDigits100[2 * k + 0];
   622     *buf++ = kDigits100[2 * k + 1];
   624     uint32_t 
const q = k / 100;
   625     uint32_t 
const r = k % 100;
   627     *buf++ = kDigits100[2 * r + 0];
   628     *buf++ = kDigits100[2 * r + 1];
   634 char* FormatBuffer(
char* buf, 
int k, 
int n) {
   645   if (k <= n && n <= 21) {
   648     std::memset(buf + k, 
'0', static_cast<size_t>(n - k));
   657   if (0 < n && n <= 21) {
   661     std::memmove(buf + (n + 1), buf + n, static_cast<size_t>(k - n));
   663     return buf + (k + 1);  
   666   if (-6 < n && n <= 0) {
   669     std::memmove(buf + (2 + -n), buf, static_cast<size_t>(k));
   672     std::memset(buf + 2, 
'0', static_cast<size_t>(-n));
   673     return buf + (2 + (-n) + k);  
   683     std::memmove(buf + 2, buf + 1, static_cast<size_t>(k - 1));
   689   return AppendExponent(buf, n - 1);