幻想森林

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 2994|回复: 5

[通用编程] 数值问题

[复制链接]

313

主题

1574

帖子

1万

积分

⑧专业

*永恒国度*

积分
14145
QQ
发表于 2008-4-12 15:16:42 | 显示全部楼层 |阅读模式
double h=0.1,r=0.1;
float k=r*(h*h);
int n=(1-0)/h;
int m=(0.005-0)/k;
printf("%d\n",m);

像这样一个程序,为什么它得出的结果会是4呢?

而像这样
double h,i;
int m;
h=0.005;
i=0.001;
m=h/i;
printf("%d\n",m);
为什么它的结果又是正确的呢?
[img][/img] http://shop33698673.taobao.com被别人嫉妒,证明你优秀,嫉妒别人说明你无能
回复

使用道具 举报

8

主题

215

帖子

2223

积分

⑥精研

积分
2223
发表于 2008-4-12 23:18:09 | 显示全部楼层
首先,这是C吧?C的话浮点数一般是用IEEE 754标准定义的单精度浮点数与双精度浮点数。
这些浮点数都是会损失精度的,在计算中会带来偏差。

0.005在双精度浮点数的编码是:
0 01111110111 0100011110101110000101000111101011100001010001111011
很明显不是一个准确值。

0.001在双精度浮点数的编码是:
0 01111110101 0000011000100100110111010010111100011010100111111100
很明显也不是一个准确值。

0.1在双精度浮点数编码下同样不是一个准确值。
0.1 * 0.1 * 0.1得到的双精度浮点数的编码是:
0 01111110101 0000011000100100110111010010111100011010100111111101
与上面的0.001比较:最后一位得到的结果不一样。

于是,如果用字面量的0.005除以0.001,有办法算出一个合理的值(在这里,得到的就会是5)。但如果这个近似0.001的值是算出来的,它的值很可能与字面量的0.001不一样。可以看到0.1*0.1*0.1得到的值大于0.001。所以0.005除以一个稍微比0.001大的值,得到的是4.9xxxx。被转换为整型之后,小数部分被抛弃,得到的就是4。
回复 支持 反对

使用道具 举报

7

主题

190

帖子

1766

积分

⑥精研

....

积分
1766
发表于 2008-4-13 13:46:36 | 显示全部楼层
楼上解释的很清楚。 UP了
萝卜啊,白菜啊,土豆星啊,梦想有爱啊。
回复 支持 反对

使用道具 举报

550

主题

9116

帖子

214748万

积分

超级版主

如同神一般的存在,腿神!拖后腿的神~~

Rank: 8Rank: 8

积分
2147483647
发表于 2008-4-14 14:28:32 | 显示全部楼层
原来如此。。。书上写的会有误差,现在找到例子了
我就是你们的神,庶民们,追随我吧!跟着我一起拖后腿!
回复 支持 反对

使用道具 举报

313

主题

1574

帖子

1万

积分

⑧专业

*永恒国度*

积分
14145
QQ
 楼主| 发表于 2008-4-16 16:24:20 | 显示全部楼层
那請問這個雙精度浮點數編碼是怎麼得到的?
[img][/img] http://shop33698673.taobao.com被别人嫉妒,证明你优秀,嫉妒别人说明你无能
回复 支持 反对

使用道具 举报

8

主题

215

帖子

2223

积分

⑥精研

积分
2223
发表于 2008-4-16 17:37:48 | 显示全部楼层
可以根据IEEE754的规范自己算……
想在C里看的话,如果是little-endian的平台,用printf("%x%x", myDouble)能看到一个十六进制的值,这个值的右边8位是高32位,左边的8位是低32位。左边不足32位的话前面都是0。
float的话直接printf("%x", myFloat)就是。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|幻想森林

GMT+8, 2024-5-6 18:10 , Processed in 0.024907 second(s), 21 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表