【发布时间】:2015-03-09 11:59:53
【问题描述】:
遇到一个关于double转ascii的问题,搜索后得到了Florian的论文"Printing Floating-Point Numbers Quickly and Accurately with Integers",Grisu2算法真的很棒,速度也快很多。我理解了 Grisu2 的想法,但我不知道如何实现它,所以我得到了Florian's C implement,这对我来说有点复杂,我仍然不太了解 2 个函数: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;
}
【问题讨论】:
-
我可能不必问,但您知道,在不使用 >2010 算法的情况下,您将在一个代码行中获得大多数情况下可接受的结果?
-
那么阅读实际论文呢?
-
这个link是否有具体问题无法解答? (由您提供)您引用的论文中的这句话:正确的打印成为许多语言规范的一部分,此外所有主要的 C 库(因此所有程序都依赖于 printf functions) 适应了准确的算法并现在打印正确的结果,表明它可能是您正在使用的 C 版本(如果它相当新)已经包含准确地打印的能力。 (第 1 页,第二列,第二段)
-
@deviantfan @ryyker 好吧,我确实知道如何使用
sprintf来获得正确的结果,但我的问题是,即使在阅读和思考了仔细看实际的纸张。
标签: c algorithm precision ieee-754 floating-point-conversion