我遇到了一个关于把double转换成ascii的问题,在搜索之后,我得到了弗洛里安的论文“用整数快速准确地打印浮点数”,Grisu2算法真的很棒,而且速度更快。我已经理解了Grisu2 2的想法,但我不知道如何实现它,所以我得到了弗洛里安C工具,这对我来说有点复杂,我仍然不能真正理解两个函数: cached_power和digit_gen,谁知道Grisu2能帮助我吗?
评论显示了我的问题。
// 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;
}
--这个是更复杂的
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;
}
发布于 2015-03-10 06:25:40
第一部分:
diy_fp_t
是一个浮点结构,它以曼蒂斯和指数作为单独的成员(不是很有趣,但它在这里:fp.h)。
cached_power(k)
的目的是计算10^k的值,并将结果保存到diy_fp_t
中。因为这对计算机来说既不简单,也不快,作者有一个数组(一个表示mantisse,一个表示指数),这些数组(尽可能好)是必要的幂(Grisu将不会使用其他的幂)。本文第四章和第五章对此作了解释。
示例代码中的数组以10^(-343)
的值开头,这是0xbf29dcaba82fdeae * 2^(-1203)
,= 13774783565108600494 * 2^(-1203)
。10^(-342)
属于下一个数组位置,依此类推。因为-343
有数组索引[0]
,所以首先添加343。
https://stackoverflow.com/questions/28941497
复制相似问题