`
rollstone
  • 浏览: 37188 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

浮点数的比较

阅读更多
一浮点数的知识
1.首先浮点数不用补码表示,只有int型才用补码表示。
2.计算机能精确表示的数值是有限的,离散的,而现实中的实数是连续的,这就必然有精度的要求。二进制的小数更糟糕,能精确表示的更少。
例如:
0.1D,表示成二进制的时候是循环的
0.0 0011 0011 0011......B
根据IEEE标准754:
32位的float类型有效位为23位。前面还有个隐含位。
所以float类型最多的有效位:24位(这个位是bit,是对2进制来说的)。
0.1d
在内存中的表示为:
0  01111011    10011001100110011001101B
第一位为符号位,
接下来8位为指数:实际指数+2^n-1=-4+127=123=01111011
接下来是23位有效位,前面还隐含一个有效位1.

而这个数
0  01111011    10011001100110011001101B
转化为10进制为:
0.100000001D
有0.000000001D的误差。

对于不同的数,误差补一样,可能在第7位,可能在第8位,第9位。但是能保证在小数点后面的六位是准确的。
http://cprogramsjzu.blog.sohu.com/81276949.html。
象fprintf函数输出float类型的时候,一般只输出小数点后面六位。
至于二进制的24位有效位,对应10进制的多少有效位,我不知道怎样计算,我看网上的方法都是错的。


二.浮点数的比较
1.浮点数精确比较
现在我们知道在计算机内浮点数本身是可以精确比较的。但是大部分实数不能精确的转化为计算机内部的浮点数(基本都是近似值)。
浮点数运算还是要用10进制浮点数来避免误差。
1.软件方法,据说java可以。我没用过。
2.硬件。传说IBM会生产进行10进制浮点运算的芯片。

所以根据已经了解到的知识,想把现实中的数,映射到计算机中进行比较,是不可能的,因为可能有N个实数对应于计算机中的一个数。
有意义的比较应该是带单位的数据在误差范围(这个误差根据需要设置)内的比较。
例如:身高,单位为厘米的时候,精确到小数点后面两位:
1.751cm我们认为等于1.75cm。

网上很多地方写浮点数比较的时候,会这样写:
fabs(A-B) < epsilon
一般将epsilon定义为:0.000001D
浮点数跟定点数比较是不对的。除非有现实的意义。
凭什么相差位epsilon就表示相等阿。大量不等的数据,这样判断都相等了。

除非限定输入,例如都是float类型,最小为:
#define FLT_MIN              1.1754943508222875E-38F
f1-f2 <FLT_MIN 则表示相等,这个还象话。

2.有现实意义的误差范围内的比较怎么写?
如果给定一个误差范围,在这个误差范围内则表示这两个数相等,应该怎么写?
我觉得得看需求。

三. 一个有趣的例子
/* -------------a.c------------------ */
#include <stdio.h>
double f(int x)
{
return 1.0 / x ;
}
void main()
{
double a , b;
int i ;
a = f(10) ;
b = f(10) ;
i = a == b ;
printf( "%d\n" , i ) ;
}

/*---------------- b.c ----------------------*/
#include <stdio.h>
double f(int x)
{
return 1.0 / x ;
}
void main()
{
double a , b , c;
int i ;
a = f(10) ;
b = f(10) ;
c = f(10) ;
i = a == b ;
printf( "%d\n" , i ) ;
}
前一个结果为0,后一个为1.


原因看这个:
http://xenyinzen.wikidot.com/reship:080123-28
总结下来就是cpu内的精度比double都高。第一个程序:计算完a,a的值返回内存,被转化为64的double精度丢失。而b计算完之后,不返回内存大概精度80位左右,跟a比较。所以不等。
第二个都返回内存了。


http://www.cnblogs.com/diylab/archive/2011/01/10/1562407.html

http://cprogramsjzu.blog.sohu.com/81276949.html

http://topic.csdn.net/u/20070926/20/dee5a142-af94-4193-8752-3bf1ed12df28.html

http://blog.csdn.net/happy__888/article/details/289373

http://blog.vckbase.com/bruceteen/archive/2006/01/20/17193.html


http://www.cnblogs.com/FlyingBread/archive/2009/02/15/660206.html


http://zh.wikipedia.org/wiki/IEEE_754


http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm


http://blog.vckbase.com/bruceteen/articles/240.html


http://www.cnblogs.com/bossin/archive/2007/04/08/704567.html


http://rangercyh.blog.51cto.com/1444712/405375
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics