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

2022-02-08 15:41:09 +08:00
 gollum11233

原型是一本讲算法的书的课后题,《数据结构与算法分析-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 型是用指数形式存储的所以存储的其实是个近似值,但是不太懂这个保证精度的原理,能否详细讲解一下

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

724 次点击
所在节点    问与答
5 条回复
gollum11233
2022-02-08 15:42:25 +08:00
敲的时候代码还是排版好的,不知道为什么发出来就成一坨屎了。。。请见谅
hello2090
2022-02-08 15:48:16 +08:00
没仔细看代码,看一眼的感觉是,比如说 13.666666666

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

你这函数第二个参数 len 不就是控制打印位数的吗

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/832464

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX