float转int出问题了,请教下!

xiezifang 2010-05-17 09:08:25
float转整型出问题了,以下代码中c和d的值不一样,请问大家为什么呢?
为何分开两步写就好了,d得到9就是我想要的值,而d却不为9,为何?
main()
{
float a=0.9,b;
int c,d;
b=a*10.0;
c=(int)b;//结果1
d=(int)(a*10.0);//结果2
}
...全文
782 29 打赏 收藏 转发到动态 举报
写回复
用AI写文章
29 条回复
切换为时间正序
请发表友善的回复…
发表回复
yayi130 2010-05-18
  • 打赏
  • 举报
回复
我不懂但我想知道
guow043 2010-05-18
  • 打赏
  • 举报
回复
a =0.9 看看在栈里的存储
狂龙骄子 2010-05-18
  • 打赏
  • 举报
回复
此前遇到过这样的问题,没有深究。

学习~~~
npngsc 2010-05-17
  • 打赏
  • 举报
回复
看一些ieee的浮点表示规则就知道为啥了
jianzhentianxia 2010-05-17
  • 打赏
  • 举报
回复
通过观察该程序在 gcc, g++ 编译器在32位cpu下的汇编码,发现:
1. a 的值 不是 0.9, 而是比0.9小的一个浮点数,该数是0.9的近似表示。(大家可通过单步运行查看变量值观测)。 浮点数表示国际标准:IEEE 754。
2. b 的值 的获得 是通过 浮点指令计算得到,值为0.9,这个值的获得是将浮点寄存器中的值发送到栈上时,出现的转换。在浮点处,a*10.0的值实际上要是 8.9999... 。大家可通过查看浮点指令的语义及float 与 int 的转换标准理解。
3. c,d的说法,可参考 wdy0725的帖子~
liutengfeigo 2010-05-17
  • 打赏
  • 举报
回复
编译器的问题。别深究~!
wdy0725 2010-05-17
  • 打赏
  • 举报
回复
VS 2005 下是这样的:

a 0.89999998 float // a = 0.9 在内存中的表示
b 9.0000000 float // 计算后 b 的值
c 9 int // c值
d 8 int // d值

c 值由 b 值而来, d 值是直接被截断的,这两个好理解。
就是b值,为什么是 9.0000000 而不是 8.9999998呢?因为这个值无法在我的机子上精确表示,所以就被近似表示了。
z569362161 2010-05-17
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 pl879 的回复:]
貌似大家都没解释到为什么float型的0.9*10.0为什么会是8.999999999来着?
[/Quote]

去问编译器
pl879 2010-05-17
  • 打赏
  • 举报
回复
貌似大家都没解释到为什么float型的0.9*10.0为什么会是8.999999999来着?
aaabianhuakai 2010-05-17
  • 打赏
  • 举报
回复
float和double占得位数不一样

而小数在计算机中本来就是近似表示的

所以根本不能假设成你赋值0.9 他就保存0.9的情况

double的设计可以让含有很多位小数的值表示的更精确,应该根据需要来使用
某某9 2010-05-17
  • 打赏
  • 举报
回复
改为double的话 就都是9了

不知道为什么float不一样?
aaabianhuakai 2010-05-17
  • 打赏
  • 举报
回复
你可以这样试试

float a=0.9f*10.0;

double b=0.9f*10.0;

调试运行 看一下内存中的值

可以看出 a是9.00000....
b是8.9......

当转化成int的时候 是直接把小数点后面截断的

所以你看到的是9和8

wzywsk 2010-05-17
  • 打赏
  • 举报
回复
貌似小数转为二进制后这保留4位 你这样转换就断截了~~~
Myth_cn 2010-05-17
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 sky198306 的回复:]

楼上说得不对,小数位也一样可以精确表示~
[/Quote]
一些小数位是可以精确表示的,更多的无法精确表示。
楼主这个如果全部用float的话或者全部用double的话都没有问题,但是将float和double的乘积赋值给int就有问题了,难道跟内存排布有关系么?期待高人解答
npngsc 2010-05-17
  • 打赏
  • 举报
回复
分步为9,单步为8,我试了一下
GCC: (Ubuntu 4.3.3-5ubuntu4) 4.3.3
冰河漩涡 2010-05-17
  • 打赏
  • 举报
回复
d=(int)(a*10.0+0.1);//+0.1就可以了
huanmie_09 2010-05-17
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 zhongguang1019 的回复:]
d=(int)(a*10.0);//结果2 结果是什么?是0吗?
[/Quote]
结果是8.
浮点数运算存在一定的精度误差。
强制转型丢失了数据。
楼主可以打印一下看看:
printf("a*10.0=%.10f\n", a*10.0);
c=(int)b; //这样强制转型,小数点后的数字被丢失了,因此c为8。
pl879 2010-05-17
  • 打赏
  • 举报
回复
神奇,为什么结果2是8?
zhongguang1019 2010-05-17
  • 打赏
  • 举报
回复
d=(int)(a*10.0);//结果2 结果是什么?是0吗?
昵称很不好取 2010-05-17
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 sky198306 的回复:]
楼上说得不对,小数位也一样可以精确表示~
[/Quote]
那0.9的精确表示的二进制怎么样?写出来看看
加载更多回复(9)

69,382

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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