我试图弄清楚如何在不使用库函数的情况下打印浮点数。打印浮点数的小数部分非常容易。打印整体部分更难:
static const int base = 2;
static const char hex[] = "0123456789abcdef";
void print_integral_part(float value)
{
assert(value >= 0);
char a[129]; // worst case is 128 digits for base 2 plus NUL
char * p = a + 128;
*p = 0;
do
{
int digit = fmod(value, base);
value /= base;
assert(p > a);
*--p = hex[digit];
} while (value >= 1);
printf("%s", p);
}
FLT_MAX
使用 base 2 和 base 16 完美打印作品的组成部分:
11111111111111111111111100000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000 (base 2)
ffffff00000000000000000000000000 (base 16)
但是,以 10 为基数打印会导致前 7 位数字后出现错误:
340282368002860660002286082464244022240 (my own function)
340282346638528859811704183484516925440 (printf)
我认为这是除以 10 的结果。如果我使用 double 而不是 float,效果会更好:
340282346638528986604286022844204804240 (my own function)
340282346638528859811704183484516925440 (printf)
(如果您不相信printf
,请进入2^128-2^104
Wolfram Alpha。它是正确的。)
现在,如何printf
设法打印正确的结果?它是否在内部使用了一些 bigint 设施?还是我缺少一些浮点技巧?