f1 = f1 * 100;
//float f2=1.0f;
int a = (int)f1;
这样a就为0;但如果把第三行的注释去掉以后,a就等于1了。为什么?????还有为什么a会为0;
21 个解决方案
#1
f2的注释和 a的值没有关系的吧! 还有a的值是1啊! gcc 4.4.3
ps:强转有精度丢失是正常的!
ps:强转有精度丢失是正常的!
#2
浮点数的误差 100*0.01 != 1 很正常
#3
float是16位的,表达0.01的时候,实际上是0.0099999998,*100也不到1
不过我在VS2008的环境下运行,a是等于1的
不过我在VS2008的环境下运行,a是等于1的
#4
那怎么来避免浮点型产生的误差那?
#5
下断点检查的时候f1显示也是1.0f但是一转话成int就变成0了。
#6
我是在vc环境上运行的、
#7
不会出现这种情况啊
#8
我在一楼就说明了!不可能的!这应该是代码有bug或者编译器有问题!
#9
#10
不会出现这种情况啊
下断点检查的时候f1显示也是1.0f但是一转话成int就变成0了。
#11
#12
vc6.0的编译环境,我还能骗你们怎么的。哎
#13
编译器不同,你的2008做优化了吧,我这边只能用vc的。
编译器不同,你的2008做优化了吧,我这边只能用vc的。
不会出现这种情况啊
下断点检查的时候f1显示也是1.0f但是一转话成int就变成0了。
编译器不同,你的2008做优化了吧,我这边只能用vc的。
#14
不要将0.01写到代码中
用scanf或者cin>>读取 f1值。
用scanf或者cin>>读取 f1值。
#15
浮点数无法精确表示0.01这个小数
在执行乘除之前,精度就已经损失了
在执行乘除之前,精度就已经损失了
#16
http://www.cnblogs.com/dolphin0520/archive/2011/10/02/2198280.html
应该是和编译软件有关,在linux上确认,输出是正确的。
应该是和编译软件有关,在linux上确认,输出是正确的。
#17
精度相关的问题。没有哪个对哪个错误,只要强转整形的误差在1以内都是正确的(当然是转小不转大才能算正确)
解决方法当然就是四舍五入了。。
(int)(f1+0.5f)
如果确实是想补到边界,也得先确定一个误差精度(个人觉得意义不大),比如百分之1:
(int)(f1+0.01f)
其实这种问题就是浮点数比较的问题。而浮点数比较是不能用简单如整形或者指针的表达方式解决的:
if(i1 != 0)正常的表达方式;
if(f1 != 0.0f)往往得不到期望的响应效果
解决方法当然就是四舍五入了。。
(int)(f1+0.5f)
如果确实是想补到边界,也得先确定一个误差精度(个人觉得意义不大),比如百分之1:
(int)(f1+0.01f)
其实这种问题就是浮点数比较的问题。而浮点数比较是不能用简单如整形或者指针的表达方式解决的:
if(i1 != 0)正常的表达方式;
if(f1 != 0.0f)往往得不到期望的响应效果
#18
这个应该是编译器优化+调试器Bug吧。 理论上不应该的。
至于 0.01 * 100 == 1 基本不会出问题,0.01 * 100虽然在二进制表示下基本是 0.9999... , 但 1.0 也是一样的值, 所以 0.01 * 100 == 1.0 一般是没有问题的。
至于 0.01 * 100 == 1 基本不会出问题,0.01 * 100虽然在二进制表示下基本是 0.9999... , 但 1.0 也是一样的值, 所以 0.01 * 100 == 1.0 一般是没有问题的。
#19
不要被你的显示器说欺骗
#20
用10进制小数不能精确表示某些三进制小数0.1(3)=0.33333333333……(10)
同理,用二进制小数也不能精确表示某些10进制小数。
同理,用二进制小数也不能精确表示某些10进制小数。
#21
你加一个容差,编译器对浮点都是不准确的,f1 = f1 * 100;改为f1 = (f1+1e-6) * 100;试试
#1
f2的注释和 a的值没有关系的吧! 还有a的值是1啊! gcc 4.4.3
ps:强转有精度丢失是正常的!
ps:强转有精度丢失是正常的!
#2
浮点数的误差 100*0.01 != 1 很正常
#3
float是16位的,表达0.01的时候,实际上是0.0099999998,*100也不到1
不过我在VS2008的环境下运行,a是等于1的
不过我在VS2008的环境下运行,a是等于1的
#4
那怎么来避免浮点型产生的误差那?
#5
下断点检查的时候f1显示也是1.0f但是一转话成int就变成0了。
#6
我是在vc环境上运行的、
#7
下断点检查的时候f1显示也是1.0f但是一转话成int就变成0了。
#8
下断点检查的时候f1显示也是1.0f但是一转话成int就变成0了。
我在一楼就说明了!不可能的!这应该是代码有bug或者编译器有问题!
#9
不会出现这种情况啊
下断点检查的时候f1显示也是1.0f但是一转话成int就变成0了。
#10
不会出现这种情况啊
下断点检查的时候f1显示也是1.0f但是一转话成int就变成0了。
#11
#12
vc6.0的编译环境,我还能骗你们怎么的。哎
#13
编译器不同,你的2008做优化了吧,我这边只能用vc的。
编译器不同,你的2008做优化了吧,我这边只能用vc的。
不会出现这种情况啊
下断点检查的时候f1显示也是1.0f但是一转话成int就变成0了。
编译器不同,你的2008做优化了吧,我这边只能用vc的。
#14
不要将0.01写到代码中
用scanf或者cin>>读取 f1值。
用scanf或者cin>>读取 f1值。
#15
浮点数无法精确表示0.01这个小数
在执行乘除之前,精度就已经损失了
在执行乘除之前,精度就已经损失了
#16
http://www.cnblogs.com/dolphin0520/archive/2011/10/02/2198280.html
应该是和编译软件有关,在linux上确认,输出是正确的。
应该是和编译软件有关,在linux上确认,输出是正确的。
#17
精度相关的问题。没有哪个对哪个错误,只要强转整形的误差在1以内都是正确的(当然是转小不转大才能算正确)
解决方法当然就是四舍五入了。。
(int)(f1+0.5f)
如果确实是想补到边界,也得先确定一个误差精度(个人觉得意义不大),比如百分之1:
(int)(f1+0.01f)
其实这种问题就是浮点数比较的问题。而浮点数比较是不能用简单如整形或者指针的表达方式解决的:
if(i1 != 0)正常的表达方式;
if(f1 != 0.0f)往往得不到期望的响应效果
解决方法当然就是四舍五入了。。
(int)(f1+0.5f)
如果确实是想补到边界,也得先确定一个误差精度(个人觉得意义不大),比如百分之1:
(int)(f1+0.01f)
其实这种问题就是浮点数比较的问题。而浮点数比较是不能用简单如整形或者指针的表达方式解决的:
if(i1 != 0)正常的表达方式;
if(f1 != 0.0f)往往得不到期望的响应效果
#18
这个应该是编译器优化+调试器Bug吧。 理论上不应该的。
至于 0.01 * 100 == 1 基本不会出问题,0.01 * 100虽然在二进制表示下基本是 0.9999... , 但 1.0 也是一样的值, 所以 0.01 * 100 == 1.0 一般是没有问题的。
至于 0.01 * 100 == 1 基本不会出问题,0.01 * 100虽然在二进制表示下基本是 0.9999... , 但 1.0 也是一样的值, 所以 0.01 * 100 == 1.0 一般是没有问题的。
#19
不要被你的显示器说欺骗
#20
用10进制小数不能精确表示某些三进制小数0.1(3)=0.33333333333……(10)
同理,用二进制小数也不能精确表示某些10进制小数。
同理,用二进制小数也不能精确表示某些10进制小数。
#21
你加一个容差,编译器对浮点都是不准确的,f1 = f1 * 100;改为f1 = (f1+1e-6) * 100;试试