
原型是一本讲算法的书的课后题,《数据结构与算法分析-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 型是用指数形式存储的所以存储的其实是个近似值,但是不太懂这个保证精度的原理,能否详细讲解一下
本人新手,诚心请教各位大佬,轻喷
1 gollum11233 OP 敲的时候代码还是排版好的,不知道为什么发出来就成一坨屎了。。。请见谅 |
2 hello2090 2022-02-08 15:48:16 +08:00 via iPhone 没仔细看代码,看一眼的感觉是,比如说 13.666666666 这个函数的功能是四舍五入显示前 n 位? num+=add 就是四舍五入用的吧 |
3 msg7086 2022-02-08 15:52:30 +08:00 四舍五入。因为 num 到 n 做了强制类型转换,截断了小数,所以要先+0.5 来做四舍五入。 |
4 gollum11233 OP @hello2090 是要求输出任意输入的实数,就是输入的小数是什么输出原样的小数,比如 13.666666666 不能显示成 13.66666667 ,做如果是做四舍五入的话,那用 0.6 行不行呢 |
5 hello2090 2022-02-08 16:40:18 +08:00 via iPhone |