title: how does Florian's Grisu2 algorithm work?
body: <p>I come across a problem about converting double to ascii, after searching, I got Florian's paper <a href="http://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf" rel="nofollow noreferrer">"Printing Floating-Point Numbers Quickly and Accurately with Integers"</a>, Grisu2 algorithm is really awesome and much faster. I have understood Grisu2's idea but I don't know how to implement it, so I got <a href="http://florian.loitsch.com/publications" rel="nofollow noreferrer">Florian's C implement</a>, it's a little complicated for me and I still don't really understand 2 functions: cached_power and digit_gen, could anyone who knows Grisu2 help me?</p>
  
  <p>Comments show my question.</p>
  
  <pre><code>    //    cached_power function:
  
  static const uint64_t powers_ten[] = {0xbf29dcaba82fdeae , 0xeef453d6923bd65a,...};  
  //how do these numbers precomputed 
  static const int powers_ten_e[] = {-1203 , -1200 , -1196 , -1193 , -1190 , ...};//and what do they mean?
  
  static diy_fp_t cached_power(int k) 
  {//does this function mean give k and return the normalized 10^k diy_fp_t?
        diy_fp_t res;
        int index = 343 + k;//why add 343?
        res.f = powers_ten[index];
        res.e = powers_ten_e[index];
        return res;
  }
  </code></pre>
  
  <p><strong><em>this one is more complicated</em></strong></p>
  
  <pre><code>void digit_gen(diy_fp_t Mp, diy_fp_t delta,//Is Mp normalized?
  char* buffer, int* len, int* K) 
  {
       uint32_t div; int d, kappa; diy_fp_t one;
       one.f = ((uint64_t)1) &lt;&lt; -Mp.e; one.e = Mp.e;//what if Mp.e is positive? what's the purpose of one?
       uint32_t p1 = Mp.f &gt;&gt; -one.e; /// Mp_cut// what does p1 mean?
       uint64_t p2 = Mp.f &amp; (one.f - 1);//what does p2 mean?
       *len = 0; kappa = 3; div = TEN2;//why kappa=3 and div=100? is kappa related to div?
      while (kappa &gt; 0) 
      {    /// Mp_inv1  //what does this loop mean?
           d = p1 / div;
           if (d || *len) buffer[(*len)++] = '0' + d;
           p1 %= div; kappa--; div /= 10;
           if ((((uint64_t)p1) &lt;&lt; -one.e) + p2 &lt;= delta.f) 
           { /// Mp_delta
               *K += kappa; return;
           }
      }
      do 
      {  //what does this loop mean?
           p2 *= 10;
           d = p2 &gt;&gt; -one.e;
           if (d || *len) buffer[(*len)++] = '0' + d; /// Mp_inv2
           p2 &amp;= one.f - 1; kappa--; delta.f *= 10;// p2&amp;=one.f-1 means what?
      } while (p2 &gt; delta.f);
      *K += kappa;
  }
  </code></pre>