前些日子在使用Kinsol库(求解非线性方程的数值库)时,出现死循环。调试跟踪,发现浮点型数据异常,异常的数据使得大小比较失效,无法退出循环。这个问题涉及到浮点型数据的具体构造,详细介绍可参考下文:http://steve.hollasch.net/cgindex/coding/ieeefloat.html
本文讨论怎样的运算造成异常的浮点型数据,即异常数据的来源。浮点型数据分成三类,finite型,inf型,nan型。finite型好理解,是指有限数如0,1.1等。inf型是表示无穷大数,分为正无穷和负无穷,它由非0的有限数除0得到或者超过了浮点型能够表示的最大最小数。浮点型不像整型那样除零报错。nan型即not a number, 表示这不是一个数。它是由一些无意义的运算引起的,比如0/0,inf-inf,inf*0等,这些运算不能确定结果是什么。
前两种类型是可以比较大小,比如:1<inf,inf > 3,inf > -inf,inf == inf。这些比较是有意义的。但不能和nan型比较,如果比较则总返回0(返回什么值,大家最好自己做测试),我遇到的问题就是在比较表达式中出现了nan型数。
要判断一个浮点数是否是inf或者nan,有函数int _isnan(double x)和int _finite(double x),在float.h中声明。