关于小数点后精确度的问题

wmlysc 2010-02-28 12:13:34

main()
{
float i=2.3,k,j=5;
k=j*i;
printf("%f\n",k);
return 0;
}
上面这个得出来的是 11.500000


main()
{
float i=2.3,k,j=5;
k=j*i;
printf("%.10f\n",k);
return 0;
}
而上面的出来的却是 11.4999997616

并且提示这个 warning C4305: 'initializing' : truncation from 'const double' to 'float'

请问这是为什么?编译环境为vc6.0 为什么会出现这种情况,为什么精确到小数点后10位得出的结果不是 11.5000000000 。是我的程序语法有问题么?另外这句话什么意思?我看不懂,呵呵。

望高手解答下,谢了。
...全文
362 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
白云飘飘飘 2010-02-28
  • 打赏
  • 举报
回复
电脑是用二进制小数来表示十进制小数的,但二进制小数并不能一点不差地表示十进制小数,所以会有一定的误差。第二个更准一些,第一个看起来准确是因为向上舍入了
stardust20 2010-02-28
  • 打赏
  • 举报
回复
float i=2.3f,k,j=5;//在2.3后面加个f代表它是一个float型的数。。。不然默认是'const double' 的。。。
nwpulei 2010-02-28
  • 打赏
  • 举报
回复
引用 6 楼 wmlysc 的回复:
楼上的,谢谢你这么详细的回答,请问玩c用什么呢?我是新手,麻烦了。

c只是语言而已。要是IDE环境那就多了。
新手可以用vc++6.0
听说dev也不错,只不过没用过。
nwpulei 2010-02-28
  • 打赏
  • 举报
回复
还是看汇编清楚
wmlysc 2010-02-28
  • 打赏
  • 举报
回复
楼上的,谢谢你这么详细的回答,请问玩c用什么呢?我是新手,麻烦了。
theone11 2010-02-28
  • 打赏
  • 举报
回复
用gcc来编译运行的话,第二个程序的结果为"11.5000000000"

另外,我用vc6试了一下,按照一楼那样加一个f是不影响运行结果的,把类型换成double就能输出"11.5000000000",另外,如果你创建一个float指针,在运算后指向k的话,同样能输出"11.5000000000",只能说是vc6这个编译器的问题了.

代码:

int main()
{
float i=2.3,k,j=5;
float *z;
k=j*i;
z = &k;
printf("%.10f\n",k);
return 0;
}


vc6中以上代码对应的汇编:

8: int main()
9: {
00401010 push ebp
00401011 mov ebp,esp
00401013 sub esp,50h
00401016 push ebx
00401017 push esi
00401018 push edi
00401019 lea edi,[ebp-50h]
0040101C mov ecx,14h
00401021 mov eax,0CCCCCCCCh
00401026 rep stos dword ptr [edi]
10: float i=2.3,k,j=5;
00401028 mov dword ptr [ebp-4],40133333h
0040102F mov dword ptr [ebp-0Ch],40A00000h
11: float *z;
12: k=j*i;
00401036 fld dword ptr [ebp-0Ch]
00401039 fmul dword ptr [ebp-4]
0040103C fstp dword ptr [ebp-8]
13: z = &k;
0040103F lea eax,[ebp-8]
00401042 mov dword ptr [ebp-10h],eax
14: printf("%.10f\n",k);
00401045 fld dword ptr [ebp-8]
00401048 sub esp,8
0040104B fstp qword ptr [esp]
0040104E push offset string "%.7f\n" (0042301c)
00401053 call printf (00401080)
00401058 add esp,0Ch
15: return 0;
0040105B xor eax,eax



vc6中楼主代码对应的汇编:

{
00401010 push ebp
00401011 mov ebp,esp
00401013 sub esp,4Ch
00401016 push ebx
00401017 push esi
00401018 push edi
00401019 lea edi,[ebp-4Ch]
0040101C mov ecx,13h
00401021 mov eax,0CCCCCCCCh
00401026 rep stos dword ptr [edi]
10: float i=2.3,k,j=5;
00401028 mov dword ptr [ebp-4],40133333h
0040102F mov dword ptr [ebp-0Ch],40A00000h
11: k=j*i;
00401036 fld dword ptr [ebp-0Ch]
00401039 fmul dword ptr [ebp-4]
0040103C fst dword ptr [ebp-8]
12: printf("%.10f\n",k);
0040103F sub esp,8
00401042 fstp qword ptr [esp]
00401045 push offset string "%.7f\n" (0042301c)
0040104A call printf (00401080)
0040104F add esp,0Ch
13: return 0;
00401052 xor eax,eax


反正我只看出printf的汇编代码,我的那个版本多了一行fld dword ptr [ebp-8],至于影响输出结果的原因,我也不太懂,反正看上去跟精度什么的不搭边,这两个程序中浮点数k的值是完全一样的,完全是printf输出的问题.

再次证明拿vc6来搞代码纯粹是浪费人参……
suanyuan 2010-02-28
  • 打赏
  • 举报
回复
float 浮點數的小數點以下,精確度有線。沒有辦法顯示小數點以下 10 位,double 才可以。
伊吹萃香 2010-02-28
  • 打赏
  • 举报
回复
这与浮点数的表示方式有关,具体的信息你可以看下IEEE浮点数标准,一个浮点数由符号位、偏值指数、尾数三部分组成。在很多情况下,它没办法精确地表达一个10进制的数字。

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧