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

2024-01-31 00:32

本文主要是介绍『踩坑记录』浮点数的比较以及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++中的区别
在这里插入图片描述
在这里插入图片描述
上述官方文档中可以看出,二者基本没有区别

这篇关于『踩坑记录』浮点数的比较以及abs和fabs的区别的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/662045

相关文章

Java使用SLF4J记录不同级别日志的示例详解

《Java使用SLF4J记录不同级别日志的示例详解》SLF4J是一个简单的日志门面,它允许在运行时选择不同的日志实现,这篇文章主要为大家详细介绍了如何使用SLF4J记录不同级别日志,感兴趣的可以了解下... 目录一、SLF4J简介二、添加依赖三、配置Logback四、记录不同级别的日志五、总结一、SLF4J

go 指针接收者和值接收者的区别小结

《go指针接收者和值接收者的区别小结》在Go语言中,值接收者和指针接收者是方法定义中的两种接收者类型,本文主要介绍了go指针接收者和值接收者的区别小结,文中通过示例代码介绍的非常详细,需要的朋友们下... 目录go 指针接收者和值接收者的区别易错点辨析go 指针接收者和值接收者的区别指针接收者和值接收者的

在Spring Boot中浅尝内存泄漏的实战记录

《在SpringBoot中浅尝内存泄漏的实战记录》本文给大家分享在SpringBoot中浅尝内存泄漏的实战记录,结合实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录使用静态集合持有对象引用,阻止GC回收关键点:可执行代码:验证:1,运行程序(启动时添加JVM参数限制堆大小):2,访问 htt

售价599元起! 华为路由器X1/Pro发布 配置与区别一览

《售价599元起!华为路由器X1/Pro发布配置与区别一览》华为路由器X1/Pro发布,有朋友留言问华为路由X1和X1Pro怎么选择,关于这个问题,本期图文将对这二款路由器做了期参数对比,大家看... 华为路由 X1 系列已经正式发布并开启预售,将在 4 月 25 日 10:08 正式开售,两款产品分别为华

MySQL 中查询 VARCHAR 类型 JSON 数据的问题记录

《MySQL中查询VARCHAR类型JSON数据的问题记录》在数据库设计中,有时我们会将JSON数据存储在VARCHAR或TEXT类型字段中,本文将详细介绍如何在MySQL中有效查询存储为V... 目录一、问题背景二、mysql jsON 函数2.1 常用 JSON 函数三、查询示例3.1 基本查询3.2

kotlin中const 和val的区别及使用场景分析

《kotlin中const和val的区别及使用场景分析》在Kotlin中,const和val都是用来声明常量的,但它们的使用场景和功能有所不同,下面给大家介绍kotlin中const和val的区别,... 目录kotlin中const 和val的区别1. val:2. const:二 代码示例1 Java

CSS Padding 和 Margin 区别全解析

《CSSPadding和Margin区别全解析》CSS中的padding和margin是两个非常基础且重要的属性,它们用于控制元素周围的空白区域,本文将详细介绍padding和... 目录css Padding 和 Margin 全解析1. Padding: 内边距2. Margin: 外边距3. Padd

Python获取中国节假日数据记录入JSON文件

《Python获取中国节假日数据记录入JSON文件》项目系统内置的日历应用为了提升用户体验,特别设置了在调休日期显示“休”的UI图标功能,那么问题是这些调休数据从哪里来呢?我尝试一种更为智能的方法:P... 目录节假日数据获取存入jsON文件节假日数据读取封装完整代码项目系统内置的日历应用为了提升用户体验,

Springboot @Autowired和@Resource的区别解析

《Springboot@Autowired和@Resource的区别解析》@Resource是JDK提供的注解,只是Spring在实现上提供了这个注解的功能支持,本文给大家介绍Springboot@... 目录【一】定义【1】@Autowired【2】@Resource【二】区别【1】包含的属性不同【2】@

Java中的String.valueOf()和toString()方法区别小结

《Java中的String.valueOf()和toString()方法区别小结》字符串操作是开发者日常编程任务中不可或缺的一部分,转换为字符串是一种常见需求,其中最常见的就是String.value... 目录String.valueOf()方法方法定义方法实现使用示例使用场景toString()方法方法