本文主要是介绍『踩坑记录』浮点数的比较以及abs和fabs的区别,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
在C语言中,我们知道浮点数的存储方式是IEEE(电气和电子工程协会)规定的,使用三个部分表示一个浮点数:符号位、有效数字和指数位。
浮点数的比较
任意一个二进制浮点数V可以表示成下面的形式:
- V = ( − 1 ) S ∗ M ∗ 2 E V = (-1)^S*M*2^E V=(−1)S∗M∗2E,S为符号位,M为有效数字,E为指数位。
我们知道有的小数可能小数点后有很多为,比如无限循环小数、无限不循环小数,而计算机中的float和double能够表示的小数范围是有限的,因此浮点数在计算机中的存储是不精确的。
下面,我们来看一个例子:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>int main(){float n = 1 - 0.0000001;// 理论上是相同的if (n == 0.9999999){printf("hello, world!\n");}return 0;
}
运行结果如下:
从上述结果可以看出,程序判断二者是不相等的,这是因为float表示的精度达不到这么高。
我们将程序修改一下:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>int main(){float n = 1 - 0.0000001;if (fabs(n - 0.9999999) < 1e-6){printf("hello, world!\n");}return 0;
}
运行结果如下:
结论:
- 浮点数判断相等当在float或double表示精度范围内时可以直接使用==比较,但是更多情况下是比较两个数的差的绝对值小于float或double表示的精度误差就可以认为这两个浮点数相等。
- float的精度误差为1e-6,double的精度误差为1e-15。
abs和fabs的区别
首先,这两个函数在C语言中的区别:
- abs是针对整数求绝对值,定义在stdlib.h头文件中。
- fabs是针对浮点数求绝对值,fabs定义在math.h头文件中。
我们来看下面一个例子:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>int main(){// 使用abs求一个整数的绝对值printf("abs(-3): %d\n\n", abs(-3));// 使用fabs求一个整数的绝对值printf("fabs(-3)(%%d): %d\n", fabs(-3));printf("fabs(-3)(%%f): %f\n\n", fabs(-3));// 使用fabs求一个浮点数的绝对值printf("fabs(-3.14): %f\n\n", fabs(-3.14));// 使用abs求一个浮点数的绝对值printf("abs(-3.14)(%%d): %d\n", abs(-3.14));printf("abs(-3.14)(%%f): %f\n", abs(-3.14));return 0;
}
运行结果如下:
从上述运行结果可以看出,使用abs求浮点数的绝对值是有问题的,使用fabs求整数的绝对值也是有问题的,所以在C语言中求浮点数的时候一定要选对函数。
下面,我们来看一下这两个函数在C++中的区别:
从上述官方文档中可以看出,二者基本没有区别。
这篇关于『踩坑记录』浮点数的比较以及abs和fabs的区别的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!