C/C++中如何判断浮点类型相等?

Posted -飞鹤-

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C/C++中如何判断浮点类型相等?相关的知识,希望对你有一定的参考价值。

1. 浮点类型在计算中的存储格式

1.1. 小数的科学计数法

科学记数法是一种记数的方法。把一个数表示成a与10的n次幂相乘的形式(1≤|a|<10,a不为分数形式,n为整数),这种记数法叫做科学记数法。例如:19971400000000=1.99714×10^13。计算器或电脑表达10的幂是一般是用E或e,也就是1.99714E13=19971400000000。

1.2. 计算机中小数的存储格式

计算机中小数的存储格式依据IEEE 745标准制定,其有三种精度标准。分别为单精度、双精度以及扩展精度。C/C++中主要用到单精度和双精度类型,即float和double类型。

科学计数法中指数的底数是10,但是计算机存储中默认的指数底数为2.
例如,19.625,其float类型的2进制表达为:0 - 10000011 - 001 1101 0000 0000 0000 0000
尾数:

  1. 整数部分的二进制形式为:19 = 124 + 023 + 022 + 121 + 1*20 = 10011
  2. 小数部分的二进制形式为:
    0.625 * 2 = 1.250 取整 1
    0.250 * 2 = 0.5 取整0
    0.5 * 2 = 1.0 取整1
    0.0 * 2 = 0
    0.625 = 12-1 + 02-2 + 1*2-3 = 101
    101反向:(((1/2 + 0)/2 + 1)/2 = 0.625
  3. 整数加小数2进制10011.101
  4. 尾数 val 必须 1 ≤ val< 2,所以还需要再将小数点向左移动4位:1.0011101*24

指数部分
24,指数4即为指数部分。
符号位
正数0,负数1。

2. 浮点类型比较

示例1
0.5的float浮点存储格式为:1*2-1
0.1的float浮点存储格式为:因为0.1乘以2,永远无法凑整,所以0.1的尾数只能取近似值,而不是完整存储。
示例2
double a = 10000000000.000011;
double b = 10000000000.000008;
绝对误差:d1 = abs(a - b) = 0.000003
相对误差:d2 = abs(a - b ) / abs(a); (值非常小)
示例3
double a = 0.000011;
double b = 0.000008;
绝对误差:d1 = abs(a - b) = 0.000003
相对误差:d2 = abs(a - b ) / abs(a)=0.272

根据上面的示例,我们发现,

  1. 浮点类型是可以表示部分准确的实数,单独列出来,可以提高判断执行效率。
    所以:
    if (a == b) return true;
  2. 如果绝对误差在允许的范围内,那么也是肯定认为是相等的。
    if (abs(a - b) < absTh) return true;
  3. 其他情况则判断相对误差。
    if (abs(a - b) < relTh*max(abs(a), abs(b)) return true;
  4. other
    return false;

3. 完整代码

bool AlmostEquel(double _left, double _right, double _absTh = FLT_EPSILON, double _relTh = FLT_MIN)

	if (_left == _right)
	
		return true;
	

	double dev = abs(_left - _right); 
	if (dev < _absTh)
	
		return true;
	
	else 
	
		return (dev < _relTh * std::max(_right, _left));
	


4. 参考

  1. https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
  2. https://stackoverflow.com/questions/4915462/how-should-i-do-floating-point-comparison/66750064#66750064

以上是关于C/C++中如何判断浮点类型相等?的主要内容,如果未能解决你的问题,请参考以下文章

float类型和double类型的二进制存储

js中如何判断两个浮点数是不是相等

判断一个字符是不是相等,该如何表达

float和double型分别怎么存储

java float浮点型数据存储,丢失精度问题

浮点类型是如何存储的