『踩坑记录』浮点数的比较以及abs和fabs的区别

在C语言中,我们知道浮点数的存储方式是IEEE(电气和电子工程协会)规定的,使用三个部分表示一个浮点数:符号位、有效数字和指数位。

浮点数的比较

任意一个二进制浮点数V可以表示成下面的形式:

  • V = ( − 1 ) S ∗ M ∗ 2 E V = (-1)^S*M*2^E V=(1)SM2E,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++中的区别
在这里插入图片描述
在这里插入图片描述
上述官方文档中可以看出,二者基本没有区别

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值