问题描述
floata=70.075f;intbb=(int)(a*1000);floatc=a*1000;intcc=(int)c;上面的代码按理说得到的cc和bb应该一样,但实际上bb的结果为70074,cc结果是70075。很疑惑这两种写法上有什么区别,为什么会导致这样的问题?请大神分析一下。
解决方案
解决方案二:
都75啊楼主你电脑坏了吧
解决方案三:
framework4.0刚刚测试,结果都是70075
解决方案四:
引用1楼shingoscar的回复:
都75啊楼主你电脑坏了吧
解决方案五:
我的测试结果也相同,你看下是在什么位置取值不同。
解决方案六:
楼主电脑坏了,才三个小数位,明显在精度范围内
解决方案七:
vs2005,用的是netframe2.0.是不是版本不一样导致的。另外,如果a的整数部分改为63及以下就没问题。
解决方案八:
把a换成64.075在vs2005net2.0;vs2008net3.5;vs2010net4.0下都测试了一下,结果bb和cc都是74.下图是vs2010下的监视结果。
解决方案九:
{floata=70.075f;intbb=(int)(a*1000);}{floata=70.075f;floatc=a*1000;doublex=a*1000;intcc=(int)c;}
开了一个项目试了一下,确实是这样的,调试的时候不要优化代码。问题出现在floatc=a*1000;
,这个赋值会把堆栈中的运算结果值存入变量。在这个过程中,实际的值应该是x=70074.996948242188,而因为精度问题,存入c的值是c=70075.0。这也就是我们一直避免使用float类型的原因,因为精度实在是太低了。
解决方案十:
引用7楼headgo的回复:
把a换成64.075在vs2005net2.0;vs2008net3.5;vs2010net4.0下都测试了一下,结果bb和cc都是74.
结果一样说明没问题啊
解决方案十一:
奇怪的是为何两种写法有时结果还不一样,分开写有时还能得到想要的结果。
解决方案十二:
在实际编码中别写这种靠谱的代码不就完了
解决方案十三:
引用楼主headgo的回复:
floata=70.075f;intbb=(int)(a*1000);floatc=a*1000;intcc=(int)c;上面的代码按理说得到的cc和bb应该一样,但实际上bb的结果为70074,cc结果是70075。很疑惑这两种写法上有什么区别,为什么会导致这样的问题?请大神分析一下。
可能你需要贴出你的CPU的型号,以及操作系统版本号了。单精度浮点数只有7位(十进制)左右的精度,如果你将其乘以1000,那么误差也就扩大1000倍。然后你又把float直接截断为int32数字。有你这样粗放的算法,那么这种精度损失,是很正常的(最终你在int32的值上只看到4为有效数字了)。.net在不同系统版本下、不同CPU下,编译出来的代码是不同的。而不同CPU对于指令的处理肯定也是不完全相同的。即使是.net2.0framework,你用11、12年前的与2015年是随现在的软件包而发布的.net2.0,相信它的Jit编译出的代码也是有差异的。相信最近这些年的.net在保证运算效率的基础上,也能稍微提高一些精度。电脑计算的误差在所难免。所以哪怕是很简单的四则运算的数学计算,只要是反复进行复杂迭代计算(例如解三角矩阵的逆矩阵算法),数学家也要调整传统的算法,选择一种累计误差不会扩大的算法去重写。
解决方案十四:
在实际的程序设计中,可能要考虑的因素包括:原始数据的精度,是否应该使用double而不是float,是否可以随便截断小数部分而转换为int32,是否应该先进行后边的计算处理、最后才*1000(而不是先*1000),等等。用电脑搞数学计算的人在学校里学过计算精度问题。这是相关的任何一种数值计算方面的课程的教科书,在一开始就会讲到的。
解决方案十五:
引用5楼starfd的回复:
楼主电脑坏了,才三个小数位,明显在精度范围内
中毒了可能会出现这种问题。
解决方案:
引用12楼sp1234的回复:
Quote: 引用楼主headgo的回复:
floata=70.075f;intbb=(int)(a*1000);floatc=a*1000;intcc=(int)c;上面的代码按理说得到的cc和bb应该一样,但实际上bb的结果为70074,cc结果是70075。很疑惑这两种写法上有什么区别,为什么会导致这样的问题?请大神分析一下。可能你需要贴出你的CPU的型号,以及操作系统版本号了。单精度浮点数只有7位(十进制)左右的精度,如果你将其乘以1000,那么误差也就扩大1000倍。然后你又把float直接截断为int32数字。有你这样粗放的算法,那么这种精度损失,是很正常的(最终你在int32的值上只看到4为有效数字了)。.net在不同系统版本下、不同CPU下,编译出来的代码是不同的。而不同CPU对于指令的处理肯定也是不完全相同的。即使是.net2.0framework,你用11、12年前的与2015年是随现在的软件包而发布的.net2.0,相信它的Jit编译出的代码也是有差异的。相信最近这些年的.net在保证运算效率的基础上,也能稍微提高一些精度。电脑计算的误差在所难免。所以哪怕是很简单的四则运算的数学计算,只要是反复进行复杂迭代计算(例如解三角矩阵的逆矩阵算法),数学家也要调整传统的算法,选择一种累计误差不会扩大的算法去重写。
跟CPU和系统都有关系,不能一概而论。如果是64位的操作系统应该不会出问题。