Ron*_*sch 5 c precision floating-point-precision
这是我写的代码:
#include <stdio.h>
#include <stdlib.h>
int main()
{
double num;
int tmp;
printf("enter a number!\n");
scanf("%lf",&num);
tmp=num*10000;
printf(" temp=%d\n",tmp);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我输入数字1441.1441时,我得到的结果是14411440而不是14411441,这显然是将我的输入数字乘以10000后的正确结果.有人可以帮我解决这个问题吗?
pax*_*blo 10
由于绝大多数实数实际上无法准确表示,因此您可能会发现它1441.1441实际上存储为类似的东西1441.14409999_blah_blah_blah.您可以通过插入来找到:
printf ("%.50lf\n", num);
Run Code Online (Sandbox Code Playgroud)
在scanf看到之后立即(删除尾随零):
1441.14409999999998035491444170475006103515625
Run Code Online (Sandbox Code Playgroud)
现在,这实际上是基于您的输入的正确(即最接近)值.那里的下一个最高数字给你:
1441.144100000000207728589884936809539794921875
Run Code Online (Sandbox Code Playgroud)
第一个值的错误是:
0.00000000000001964508555829524993896484375
^ ~ 2 x 10^-14
Run Code Online (Sandbox Code Playgroud)
而第二个错误是:
0.000000000000207728589884936809539794921875
^ ~ 2 x 10^-13
Run Code Online (Sandbox Code Playgroud)
你可以看到后者的错误大约是后者的10倍.
当你将它乘以10000并尝试将其变为a时int,它会向下舍入(截断).这是因为(C11)标准有这样的说法6.3.1.4:
当实数浮动类型的有限值被转换为除_Bool之外的整数类型时,小数部分被丢弃(即,该值被截断为零).
你可以尝试的一件事是将你的鞋带线改为:
tmp = num * 10000 + 0.5;
Run Code Online (Sandbox Code Playgroud)
这有效地将截断转换为舍入操作.我认为这适用于所有情况,但你可能想测试它(并密切关注它)以防万一.
| 归档时间: |
|
| 查看次数: |
1473 次 |
| 最近记录: |