V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
gollum11233
V2EX  ›  问与答

请教一个打印浮点数精度的问题,为什么要把小数部分加一个 add 再进位

  •  
  •   gollum11233 · 2022-02-08 15:41:09 +08:00 · 714 次点击
    这是一个创建于 807 天前的主题,其中的信息可能已经有所发展或是发生改变。

    原型是一本讲算法的书的课后题,《数据结构与算法分析-C 语言描述》,原题目是“只使用处理 I/O 的 PrintDigit 函数,编写一个过程以输出任意实数”

    参考代码如下:

    #include <stdio.h> void PrintDigit(double , int);

    int main(int argc, char **argv) { PrintDigit(12.123456,7); putchar('\n');

    return 0;
    

    }

    void PrintDigit(double num, int len) { if(num < 0) { num = -num; putchar('-'); } int n = (int) num; int i=0; printf("%d",n);

    num = num - n;
    
    while(num > 0 && i < len)
    {
       if (i == 0)
       {            // 由于 double 小数存储方式并非确定值,而是一个近似值所以采用这种方式
            double add = 0.5;
            int j;
            for(j=0; j<len; j++)
            {
                add /= 10;
            }
            num+=add;
            putchar('.');
        }
        num = num * 10;
        n = (int) (num);
        printf("%d",n);
        num = num - n;
        i++;
    }
    

    }

    不懂的地方有两点: 1.为什么要用 0.5 来退位做加法,选用其他数是否可行 2.为什么要退位再相加才能保证精度,大概知道是因为 C 里 double 型是用指数形式存储的所以存储的其实是个近似值,但是不太懂这个保证精度的原理,能否详细讲解一下

    本人新手,诚心请教各位大佬,轻喷

    5 条回复    2022-02-08 16:40:18 +08:00
    gollum11233
        1
    gollum11233  
    OP
       2022-02-08 15:42:25 +08:00
    敲的时候代码还是排版好的,不知道为什么发出来就成一坨屎了。。。请见谅
    hello2090
        2
    hello2090  
       2022-02-08 15:48:16 +08:00 via iPhone
    没仔细看代码,看一眼的感觉是,比如说 13.666666666

    这个函数的功能是四舍五入显示前 n 位? num+=add 就是四舍五入用的吧
    msg7086
        3
    msg7086  
       2022-02-08 15:52:30 +08:00
    四舍五入。因为 num 到 n 做了强制类型转换,截断了小数,所以要先+0.5 来做四舍五入。
    gollum11233
        4
    gollum11233  
    OP
       2022-02-08 15:52:45 +08:00
    @hello2090 是要求输出任意输入的实数,就是输入的小数是什么输出原样的小数,比如 13.666666666 不能显示成 13.66666667 ,做如果是做四舍五入的话,那用 0.6 行不行呢
    hello2090
        5
    hello2090  
       2022-02-08 16:40:18 +08:00 via iPhone
    @gollum11233 四舍五入当然是+0.5 了,0.6 的话不就是 3 舍 4 入了。

    你这函数第二个参数 len 不就是控制打印位数的吗
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5360 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 08:53 · PVG 16:53 · LAX 01:53 · JFK 04:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.