『踩坑记录』浮点数的比较以及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中ArrayList和LinkedList有什么区别举例详解

《Java中ArrayList和LinkedList有什么区别举例详解》:本文主要介绍Java中ArrayList和LinkedList区别的相关资料,包括数据结构特性、核心操作性能、内存与GC影... 目录一、底层数据结构二、核心操作性能对比三、内存与 GC 影响四、扩容机制五、线程安全与并发方案六、工程

关于Spring @Bean 相同加载顺序不同结果不同的问题记录

《关于Spring@Bean相同加载顺序不同结果不同的问题记录》本文主要探讨了在Spring5.1.3.RELEASE版本下,当有两个全注解类定义相同类型的Bean时,由于加载顺序不同,最终生成的... 目录问题说明测试输出1测试输出2@Bean注解的BeanDefiChina编程nition加入时机总结问题说明

C#比较两个List集合内容是否相同的几种方法

《C#比较两个List集合内容是否相同的几种方法》本文详细介绍了在C#中比较两个List集合内容是否相同的方法,包括非自定义类和自定义类的元素比较,对于非自定义类,可以使用SequenceEqual、... 目录 一、非自定义类的元素比较1. 使用 SequenceEqual 方法(顺序和内容都相等)2.

java中不同版本JSONObject区别小结

《java中不同版本JSONObject区别小结》本文主要介绍了java中不同版本JSONObject区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们... 目录1. FastjsON2. Jackson3. Gson4. org.json6. 总结在Jav

数据库使用之union、union all、各种join的用法区别解析

《数据库使用之union、unionall、各种join的用法区别解析》:本文主要介绍SQL中的Union和UnionAll的区别,包括去重与否以及使用时的注意事项,还详细解释了Join关键字,... 目录一、Union 和Union All1、区别:2、注意点:3、具体举例二、Join关键字的区别&php

java中的HashSet与 == 和 equals的区别示例解析

《java中的HashSet与==和equals的区别示例解析》HashSet是Java中基于哈希表实现的集合类,特点包括:元素唯一、无序和可包含null,本文给大家介绍java中的HashSe... 目录什么是HashSetHashSet 的主要特点是HashSet 的常用方法hasSet存储为啥是无序的

对postgresql日期和时间的比较

《对postgresql日期和时间的比较》文章介绍了在数据库中处理日期和时间类型时的一些注意事项,包括如何将字符串转换为日期或时间类型,以及在比较时自动转换的情况,作者建议在使用数据库时,根据具体情况... 目录PostgreSQL日期和时间比较DB里保存到时分秒,需要和年月日比较db里存储date或者ti

将sqlserver数据迁移到mysql的详细步骤记录

《将sqlserver数据迁移到mysql的详细步骤记录》:本文主要介绍将SQLServer数据迁移到MySQL的步骤,包括导出数据、转换数据格式和导入数据,通过示例和工具说明,帮助大家顺利完成... 目录前言一、导出SQL Server 数据二、转换数据格式为mysql兼容格式三、导入数据到MySQL数据

关于rpc长连接与短连接的思考记录

《关于rpc长连接与短连接的思考记录》文章总结了RPC项目中长连接和短连接的处理方式,包括RPC和HTTP的长连接与短连接的区别、TCP的保活机制、客户端与服务器的连接模式及其利弊分析,文章强调了在实... 目录rpc项目中的长连接与短连接的思考什么是rpc项目中的长连接和短连接与tcp和http的长连接短

Oracle查询优化之高效实现仅查询前10条记录的方法与实践

《Oracle查询优化之高效实现仅查询前10条记录的方法与实践》:本文主要介绍Oracle查询优化之高效实现仅查询前10条记录的相关资料,包括使用ROWNUM、ROW_NUMBER()函数、FET... 目录1. 使用 ROWNUM 查询2. 使用 ROW_NUMBER() 函数3. 使用 FETCH FI