I come across a problem about converting double to ascii, after searching, I got Florian's paper "Printing Floating-Point Numbers Quickly and Accurately with Integers", 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 Florian's C implement, 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?
Comments show my question.
// 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;
}
this one is more complicated
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) << -Mp.e; one.e = Mp.e;//what if Mp.e is positive? what's the purpose of one?
uint32_t p1 = Mp.f >> -one.e; /// Mp_cut// what does p1 mean?
uint64_t p2 = Mp.f & (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 > 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) << -one.e) + p2 <= delta.f)
{ /// Mp_delta
*K += kappa; return;
}
}
do
{ //what does this loop mean?
p2 *= 10;
d = p2 >> -one.e;
if (d || *len) buffer[(*len)++] = '0' + d; /// Mp_inv2
p2 &= one.f - 1; kappa--; delta.f *= 10;// p2&=one.f-1 means what?
} while (p2 > delta.f);
*K += kappa;
}