ライブラリ関数を使用せずに浮動小数点数を出力する方法を見つけようとしています。浮動小数点数の小数部分の出力は非常に簡単であることが判明しました。積分部分を印刷するのは難しい:
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
ベース 2 とベース 16 を使用して、作品の不可欠な部分を完璧に印刷します。
11111111111111111111111100000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000 (base 2)
ffffff00000000000000000000000000 (base 16)
ただし、基数 10 で印刷すると、最初の 7 桁の後にエラーが発生します。
340282368002860660002286082464244022240 (my own function)
340282346638528859811704183484516925440 (printf)
これは 10 で除算した結果だと思います。float の代わりに double を使用すると、より良くなります。
340282346638528986604286022844204804240 (my own function)
340282346638528859811704183484516925440 (printf)
(信じられないなら、 Wolfram Alphaprintf
に入ってください。正解です。)2^128-2^104
では、どうすれprintf
ば正しい結果を出力できるのでしょうか? 内部でbigint機能を使用していますか?または、私が見逃している浮動小数点のトリックがありますか?