『踩坑记录』浮点数的比较以及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

相关文章

Vue和React受控组件的区别小结

《Vue和React受控组件的区别小结》本文主要介绍了Vue和React受控组件的区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录背景React 的实现vue3 的实现写法一:直接修改事件参数写法二:通过ref引用 DOMVu

JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法

《JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法》:本文主要介绍JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法,每种方法结合实例代码给大家介绍的非常... 目录引言:为什么"相等"判断如此重要?方法1:使用some()+includes()(适合小数组)方法2

Go之errors.New和fmt.Errorf 的区别小结

《Go之errors.New和fmt.Errorf的区别小结》本文主要介绍了Go之errors.New和fmt.Errorf的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考... 目录error的基本用法1. 获取错误信息2. 在条件判断中使用基本区别1.函数签名2.使用场景详细对

Redis中哨兵机制和集群的区别及说明

《Redis中哨兵机制和集群的区别及说明》Redis哨兵通过主从复制实现高可用,适用于中小规模数据;集群采用分布式分片,支持动态扩展,适合大规模数据,哨兵管理简单但扩展性弱,集群性能更强但架构复杂,根... 目录一、架构设计与节点角色1. 哨兵机制(Sentinel)2. 集群(Cluster)二、数据分片

Python如何实现高效的文件/目录比较

《Python如何实现高效的文件/目录比较》在系统维护、数据同步或版本控制场景中,我们经常需要比较两个目录的差异,本文将分享一下如何用Python实现高效的文件/目录比较,并灵活处理排除规则,希望对大... 目录案例一:基础目录比较与排除实现案例二:高性能大文件比较案例三:跨平台路径处理案例四:可视化差异报

一文带你迅速搞懂路由器/交换机/光猫三者概念区别

《一文带你迅速搞懂路由器/交换机/光猫三者概念区别》讨论网络设备时,常提及路由器、交换机及光猫等词汇,日常生活、工作中,这些设备至关重要,居家上网、企业内部沟通乃至互联网冲浪皆无法脱离其影响力,本文将... 当谈论网络设备时,我们常常会听到路由器、交换机和光猫这几个名词。它们是构建现代网络基础设施的关键组成

redis和redission分布式锁原理及区别说明

《redis和redission分布式锁原理及区别说明》文章对比了synchronized、乐观锁、Redis分布式锁及Redission锁的原理与区别,指出在集群环境下synchronized失效,... 目录Redis和redission分布式锁原理及区别1、有的同伴想到了synchronized关键字

基于Spring Boot 的小区人脸识别与出入记录管理系统功能

《基于SpringBoot的小区人脸识别与出入记录管理系统功能》文章介绍基于SpringBoot框架与百度AI人脸识别API的小区出入管理系统,实现自动识别、记录及查询功能,涵盖技术选型、数据模型... 目录系统功能概述技术栈选择核心依赖配置数据模型设计出入记录实体类出入记录查询表单出入记录 VO 类(用于

java中pdf模版填充表单踩坑实战记录(itextPdf、openPdf、pdfbox)

《java中pdf模版填充表单踩坑实战记录(itextPdf、openPdf、pdfbox)》:本文主要介绍java中pdf模版填充表单踩坑的相关资料,OpenPDF、iText、PDFBox是三... 目录准备Pdf模版方法1:itextpdf7填充表单(1)加入依赖(2)代码(3)遇到的问题方法2:pd

MySQL中比较运算符的具体使用

《MySQL中比较运算符的具体使用》本文介绍了SQL中常用的符号类型和非符号类型运算符,符号类型运算符包括等于(=)、安全等于(=)、不等于(/!=)、大小比较(,=,,=)等,感兴趣的可以了解一下... 目录符号类型运算符1. 等于运算符=2. 安全等于运算符<=>3. 不等于运算符<>或!=4. 小于运