打印浮点数的整数部分 [英] printing the integral part of a floating point number

查看:198
本文介绍了打印浮点数的整数部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想弄清楚如何在不使用库函数的情况下打印浮点数。打印浮点数的小数部分变得相当容易。打印整体部分比较困难:

pre $ static const int base = 2;
static const char hex [] =0123456789abcdef;

void print_integral_part(float value)
{
assert(value> = 0);
char a [129]; //最差的情况是基数为128的128位数加上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);



$ b

打印 FLT_MAX 完美的作品与基体2和基体16:

  11111111111111111111111100000000000000000000000000000000000000000000000000000000 
000000000000000000000000000000000000000000000000(基数为2)

ffffff00000000000000000000000000(基部16)

然而,在基地打印10个结果中的错误后的第一7位:

  340282368002860660002286082464244022240(我自己的函数)
340282346638528859811704183484516925440(printf的)

我认为这是除以10的结果。如果我使用double而不是float:



'pre> 340282346638528986604286022844204804240(我自己的函数)
340282346638528859811704183484516925440(printf的)

(如果您不相信 printf ,请输入 2 ^ 128-2 ^ 104 转换成Wolfram A lpha。 )



现在, printf 如何管理打印正确的结果?它在内部使用一些bigint设施吗?还是有一些浮点技巧,我缺少?

解决方案

看来,浮动到字符串转换工作马是 dtoa()函数。参见 $ d


现在,printf如何管理打印正确的结果?

我觉得这很接近魔法。至少源代码看起来像某种黑暗的咒语。

lockquote

是否在内部使用一些bigint工具?


是的,在链接的源文件中搜索 _Bigint


还是有一些浮点技巧我缺少?

可能。


I am trying to figure out how to print floating point numbers without using library functions. Printing the decimal part of a floating point number turned out to be quite easy. Printing the integral part is harder:

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);
}

Printing the integral part of FLT_MAX works flawlessly with base 2 and base 16:

11111111111111111111111100000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000 (base 2)

ffffff00000000000000000000000000 (base 16)

However, printing in base 10 results in errors after the first 7 digits:

340282368002860660002286082464244022240 (my own function)
340282346638528859811704183484516925440 (printf)

I assume this is a result of the division by 10. It gets better if I use double instead of float:

340282346638528986604286022844204804240 (my own function)
340282346638528859811704183484516925440 (printf)

(If you don't believe printf, enter 2^128-2^104 into Wolfram Alpha. It is correct.)

Now, how does printf manage to print the correct result? Does it use some bigint facilities internally? Or is there some floating point trick I am missing?

解决方案

It appears that the work horse for the float to string conversion is the dtoa() function. See dtoa.c in newlib for how they do it.

Now, how does printf manage to print the correct result?

I think it is close to magic. At least the source looks like some kind of dark incantation.

Does it use some bigint facilities internally?

Yes, search for _Bigint in the linked source file.

Or is there some floating point trick I am missing?

Likely.

这篇关于打印浮点数的整数部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆