float变量与“零值”的比较

news2024/10/5 20:28:51

目录

1.问题的引出:

2.解决方案

<1>:自定义精度

<2>:系统提供的精度

3.总结 


1.问题的引出:

浮点数在存储的时候,会存在精度的损失

那么在浮点数进行比较的时候,可不可以使用 == 来进行比较,测试代码如下:

#include<stdio.h>
int main()
{
	double a = 1.0;
	double b = 0.1;
	if ((a - 0.9) == 0.1)
	{
		printf("hahaha\n");
	}
	else
	{
		printf("hehehe\n");
	}
	return 0;
}

 在我们的认知里,a - 0.9 = 1.0-0.9 = 0.1 即程序运行成功后会输出 hahaha ,那么输出结果为是否为这样呢?

代码运行后的结果为:

得出结论:浮点数在进行比较的时候,绝对不可以直接使用 == 来进行比较


 为什么会产生上述结果呢?在此处我们将 a - 0.9 的值打印出来,同时为了更好更好地进行后续代码分析,我们将 0.1 的值也打印出来,代码为:

#include<stdio.h>
int main()
{
	double a = 1.0;
	double b = 0.1;
	printf("%.50lf\n", a - 0.9);
	printf("%.50lf\n", b);
	//保留小数点后50位
	return 0;
}

代码运行后的结果为:

 在此处我们发现,与我们想象中的并不相同,a - 0.9 != 0.1,佐证了上述比较代码的真实性。

原因是,浮点数在存储的过程中存在精度损失,会导致结果存在细微的差别。


2.解决方案

<1>:自定义精度

在此处需要介绍一个函数 --- fabs (求绝对值函数)

 我们可以自行定义一个精度,只要两浮点数相减的绝对值在我们定义的精度之内,我们就可以判定这两个浮点数相等。

对进行比较的代码稍作修改:

#include<stdio.h>
#include<math.h>
#define EPS 0.00000000000001
int main()
{
	double a = 1.0;
	double b = 0.1;
	if (fabs((a - 0.9)-0.1) < EPS)
	{
		printf("hahaha\n");
	}
	else
	{
		printf("hehehe\n");
	}
	return 0;
}

 程序运行的结果为:

 我们可以看出,此时的输出结果为 hahaha ,不在为 hehehe 。

<2>:系统提供的精度

 系统提供的精度为 --- DBL_EPSILON , 我们将其转到定义可以看到:

                               --- FLT_EPSILON

 

 XXX_EPSILON 是最小误差 --- 即:XXX_EPSILON + n 不等于 n 的最小正数

有很多数字 + n 都可以不等于 n 但是  XXX_EPSILON 是最小的。

对比较的代码进行变化,得出下列代码:

#include<stdio.h>
#include<float.h>
#include<math.h>

int main()
{
	double a = 1.0;
	double b = 0.1;
	if (fabs((a - 0.9) - 0.1) < FLT_EPSILON)
	{
		printf("hahaha\n");
	}
	else
	{
		printf("hehehe\n");
	}
	return 0;
}

​

运行结果为:

我们可以看出,此时的输出结果为 hahaha ,不在为 hehehe 。

3.总结 


 float 变量与 0 比较,只需要比较是否在精度范围内。

if (fabs((a - 0.9) - 0.1) < DBL_EPSILON) 可近似看作 if(fabs(x) <  DBL_EPSILON)

思考,在此处是否可以改为 <= ???

fabs(x)=DBL_EPSILON;

即 double y + x != y; // x  为精度 --- 引起数据变化的最小值。

参考: 0 的定义 ---  y + 0.0 = y;

我们可以得出,fabs(x) <=  DBL_EPSILON(确认是否为0的逻辑),如果 = , 就说明 x 本身已经能够引起其他和它+-的数据本身的变化了,不符合0的概念。

不可以添加等号(=)。


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/612947.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PHP——流程控制语句

if…else语句 几乎所有程序设计语言都有if语句&#xff0c;它按照条件选择执行不同的代码片段&#xff0c;PHP的if语句格式为 if&#xff08;条件&#xff09; {if 条件返回为TRUE执行的语句体; } else {if 条件返回FALSE执行的语句体&#xff1b; } 如果条件为真&#xff0c;就…

GitOps 最佳实践(下)| 基于 Amazon EKS 构建 CI/CD 流水线

了解了 GitOps 的概念以及 CI/CD 流水线的架构&#xff0c;完成了构建 GitOps 风格的 CI/CD 流水线的前两部分&#xff0c;恭喜开发者们&#xff01;我们一起在 GitOps 最佳实践的道路上已经实现了大半。接下来&#xff0c;我们一起看看构建 CI/CD 流水线最佳实践的后两个部分&…

I/O复用———常用系统调用select、poll、epoll

上周面了个实习&#xff0c;感觉自己菜的一匹&#xff0c;唉&#xff0c;理论还是没有联系实际啊&#xff0c;继续学吧。 I/O复用使得程序能同时监听多个文件描述符&#xff0c;这对提高程序的性能至关重要。通常&#xff0c;网络程序在下列情况下需要使用I/O复用技术&#xf…

01_JVM与Java体系结构

目录 三、Java及JVM简介1、Java&#xff1a;跨平台的语言2、跨语言的平台3、多语言混合编程 四、Java发展过程中的重大事件五、虚拟机和Java虚拟机1、Java虚拟机2、Jvm的位置 六、Jvm的整体结构七、Java代码的执行流程八、Jvm的架构模型九、Jvm的生命周期十、JVM的发展历程 三、…

Jenkins重启报错解决

在Jenkins上安装了一些插件后&#xff0c;需要重启Jenkins&#xff0c;由于忘了当初是怎么重启的&#xff0c;所以就问了GPT&#xff0c;下面是它的回答&#xff1a; 我想着&#xff0c;jenkins运行的好好的&#xff0c;还看什么状态&#xff0c;直接restart&#xff0c;然后……

R语言 tidyverse系列学习笔记(系列3)具体任务的处理(成绩单为例)

score成绩单 install.packages("dplyr") library(dplyr)install.packages("tibble") library(tibble)install.packages("stringr") library(stringr)score tibble(IDc("1222-1","2001-0","3321-1","4898-0…

PS 套索选区工具(1) 套索工具基础使用

套索工具和之前的几个一样 也是用来做选区的 我们先打开ps 那么 我这边已经打开了一个视图 我们在屏幕左侧这个地方找到 套索工具 右键它 这边有三个操作工具 上一文中 我们学的矩形选框工具 在图形上是有不小的限制 有点只能画方 有点只能画圆 我们右键 套索工具 这个工…

CMU 15-445 Project Project #1 - Buffer Pool(Task #1 - Extendible Hash Table)

Task #1 - Extendible Hash Table 一、题目链接二、准备工作三、部分实现四、自定义测试用例 一、题目链接 二、准备工作 见 CMU 15-445 Project #0 - C Primer 中的准备工作。 三、部分实现 Find auto Find(const K &key, V &value) -> bool override {std::sco…

【是C++,不是C艹】 类与对象 | 默认成员函数 | 构造函数 | 析构函数

&#x1f49e;&#x1f49e;欢迎来到 Claffic 的博客&#x1f49e;&#x1f49e; &#x1f449; 专栏&#xff1a;《是C&#xff0c;不是C艹》&#x1f448; 前言&#xff1a; 在完成类与对象的认识后&#xff0c;我们接着学习类与对象的第二部分&#xff1a;默认成员函数&…

基于深度学习的高精度野外烟雾检测识别系统(PyTorch+Pyside6+YOLOv5模型)

摘要&#xff1a;基于深度学习的高精度野外烟雾检测识别系统可用于日常生活中检测与定位野外烟雾目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的野外烟雾目标检测识别&#xff0c;另外支持结果可视化与图片或视频检测结果的导出。本系统采用YOLOv5目标检测…

FastReport Business Graphics .NET crack

FastReport Business Graphics .NET crack FastReport Business Graphics.NET允许您可视化层次结构信息并创建业务图以进行进一步分析。FastCube.NET允许您连接到任何应用程序。包括树图、太阳爆发图和冰柱图。 FastReport Business Graphics库允许您可视化分层数据&#xff0c…

虚幻ue镜头试拍录制器用法 5.2录制角色的的操作并按特定键播放探索

在窗口-开启镜头试拍录制器 image.png 添加源为Player image.png 这个时候录制的圆形按钮警告已经消失, 切换游戏模式为模拟 image.png 运行后点击手柄切换 进行实际的控制 image.png 点击录制之后,在cinema 的take文件夹找到文件 把文件拖动到关卡,然后 创建蓝图按L键 然后创建…

(CVPR-2023)通过有效的时空特征融合进行多模态步态识别

通过有效的时空特征融合进行多模态步态识别 paper题目&#xff1a;Multi-modal Gait Recognition via Effective Spatial-Temporal Feature Fusion paper是北航发表在CVPR 2023的工作 paper地址 Abstract 步态识别是一种生物识别技术&#xff0c;通过步行模式识别人。基于剪影…

指针 --- 进阶

先看目录&#xff0c;看你知道多少 目录 1.字符指针 2.指针数组 3.数组指针 4.数组传参和指针传参 5.函数指针 6.函数指针数组 7.指向函数指针数组的指针 8.回调函数 什么是指针&#xff0c;我们在之前的《指针》章节已经接触过了&#xff0c;我们知道了指针的概念: 1…

软件测试——功能测试,使用Java,IDEA,Selenium进行web自动化测试

视频地址&#xff1a;03-web元素定位ID_哔哩哔哩_bilibili p1.下载jdk,maven,idea p2.配置java-selenium环境正式开始&#xff1a; &#xff08;1&#xff09;创建代码&#xff1a; &#xff08;2&#xff09;第一次运行会报错&#xff1a;要下载东西 &#xff08;3&…

如何设计一个过压保护电路

有时候在电源输入处我们希望当电源的输入电压超过允许的最大值后电源与后级电路就自动断开&#xff0c;防止输入电压过高而损坏后级电路。 具有这种功能的电路叫做过压保护电路&#xff0c;英文简称叫OVP。 现在大家看到的就是一个典型的过压保护电压电路&#xff0c;主要包含…

(一)springboot实战——为什么是springboot?

前言 为什么是springboot&#xff1f;江湖夜雨&#xff0c;传说依旧&#xff0c;不懂springboot一技之长&#xff0c;如何混迹java圈&#xff0c;本节内容我们介绍一下spring的一些基本特性。尤其是springboot3的基本特性&#xff0c;使得我们更好的理解springboot3。 正文 …

【vue3】07-vue组件之间的通信-父子互传-事件总线

文章目录 Vue的组件嵌套Vue组件化-组件间通信父子组件之间通信非父子组件间的通信 Vue的组件嵌套 前面我们是将所有的逻辑放到一个App.vue中: 在之前的案例中&#xff0c;我们只是创建了一个组件App;如果我们一个应用程序将所有的逻辑都放在一个组件中&#xff0c;那么这个组…

linux下一次复制cp多个文件(含scp命令)

linux cp 参数说明 -a&#xff1a;此选项通常在复制目录时使用&#xff0c;它保留链接、文件属性&#xff0c;并复制目录下的所有内容。其作用等于dpR参数组合。 -d&#xff1a;复制时保留链接。这里所说的链接相当于Windows系统中的快捷方式。 -f&#xff1a;覆盖已经存在的目…

实训笔记6.5

实训笔记 6.5一、座右铭二、上周回顾Java基本语法1、Java的安装和环境变量的配置2、Java的标识符、关键字和保留字3、Java中的变量和常量、字面量4、数据类型5、运算符6、流程控制7、数组8、JVM内存图9、面向对象的两大概念-类和对象 三、类的组成3.1 属性的声明和使用3.1.1 属…