C++的float类型数比较问题

2023-11-07

2020.8.17更新了一下,看到了两个float数比较的,不是0值,也加进了最末尾。

相等比较

之前刷题做到一道题,看到题解很奇怪:
计算一个数字的立方根,getCubeRoot(double input)。
题解采用了二分法,但比较时并不是用直接==比较是不是达到了目标值,而是这样写的:

if(mid*mid*mid-a<0.0000001 && mid*mid*mid-a>-0.00000001)
printf("%.1lf",mid);

当时就有点懵,今天又看到了一道面试题:

写出float x 与“零值”比较的if语句

看了题解:

const float EPSINON = 0.00001; 
if ((x >= - EPSINON) && (x <= EPSINON) 

竟然又是这种形式,遂去查了相关资料,才弄明白为什么要这样写。

不可将浮点变量用“==”或“!=”与数字比较,应该设法转化成“>=”或“<=”此类形式。

EPSINON应该是一个很小的值吧 因为计算机在处理浮点数的时候是有误差的,所以判断两个浮点数是不是相同,是要判断是不是落在同一个区间的,这个区间就是 [-EPSINON,EPSINON] EPSINON一般很小,10的-6次方以下吧,具体的好像不确定的,和机器有关。

为什么浮点数不能直接作“等值比较”?

因为浮点数表示范围大,如果一个数已经很小的时候,就可以认为是0了,epsinon嘛,limit,极限什么的。也可以想一下,0.9无限循环不是等于1吗?

千万要留意,无论是float还是double类型的变量,都有精度限制。所以一定要避免将浮点变量用“==”或“!=”与数字比较,应该设法转化成“>=”或“<=”形式。

PS:一个证明的测试例子:
#include <stdio.h>
#include <stdlib.h>

main()
{
float d1, d2, d3, d4;

d1 = 194268.02;
d2 = 194268;
d4 = 0.02;

d3 = d1 - d2;
if (d3 > d4)
   printf(">0.02/n");
else if (d3 < d4)
   printf("<0.02/n");
else
   printf("=0.02/n");    

printf("%f - %f = %f /n", d1,d2,d3);

system("pause");}

请看结果:
<0.02
194268.015625 - 194268.000000 = 0.015625

即:194268.02 - 194268.0 不等于 0.02!
存进去的数居然会变!怕了吧?

4个变量改成double型的,再测试:
这是结果
<0.02
194268.020000 - 194268.000000 = 0.020000
明明是0.02啊,怎么还是小于?
这次没有改我存的数了吧?WHY?

我说,我怕了,以后我再不敢用浮点数直接作相等比较了!

还是那句话:浮点数都是有精度限制的。
所以你存的数,不一定就是你要的数。

大小比较

#define EPSILON 0.000001 //根据精度需要
if ( fabs( fa - fb) < EPSILON )//两个float
{
printf("fa<fb\n");
}

fabs函数
用法:#include <math.h>
功能:求浮点数x的绝对值
说明:计算|x|, 当x不为负时返回x,否则返回-x

abs函数是针对整数的

参考文献:
https://blog.csdn.net/azhang00000/article/details/5357134
https://blog.csdn.net/jk110333/article/details/8902707

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++的float类型数比较问题 的相关文章

随机推荐

  • Python 中的 retrying 库

    文章目录 retrying 模块 一 简介 二 使用方法 1 无参数 2 有参数 2 1 stop max attempt number 2 2 stop max delay 2 3 wait fixed 2 4 wait random m
  • 2018.6.20 Java考试试题总结(Java语言基础与面向对象编程)最新版

    Java考试试题总结 一 单选题 每题1分 50 50分 1 java程序的执行过程中用到一套JDK工具 其中javac exe指 B A java语言解释器 B java字节码编译器 C java文档生成器 D java类分解器 2 在J
  • 华为OD机试 - 连续出牌数量(Java)

    题目描述 有这么一款单人卡牌游戏 牌面由颜色和数字组成 颜色为红 黄 蓝 绿中的一种 数字为0 9中的一个 游戏开始时玩家从手牌中选取一张卡牌打出 接下来如果玩家手中有和他上一次打出的手牌颜色或者数字相同的手牌 他可以继续将该手牌打出 直至
  • 测试圈的网红工具:Jmeter到底难在哪里?!

    雨果的公司最近推出了一款在线购物应用 吸引了大量用户 然而随着用户数量的增加 应用的性能开始出现问题 用户抱怨说购物过程中页面加载缓慢 甚至有时候无法完成订单 小欧作为负责人员迫切需要找到解决方案 在学习JMeter之前 小欧只能通过手动测
  • 【画方】画方网络准入管理系统

    一 DHCP Server与DHCP准入方式 NAM内置了一个DHCP服务器 它与其它模块配合来提供DHCP准入控制功能 这个服务器与标准DHCP服务器有很大区别 它不仅利用DHCP协议实现了IP地址的中心下发功能 还利用操作系统内置的DH
  • 神经网络算法基本原理及其实现

    目录 背景知识 人工神经元模型 激活函数 网络结构 工作状态 学习方式 BP算法原理 算法实现 MATLAB 背景知识 在我们人体内的神经元的基本结构 相信大家并不陌生 看完下面这张图 相信大家都能懂 什么是人工神经网络 人工神经网络是具有
  • 《软件调试艺术》读后感七

    1 线程调试 对线程的调试用的最多的可能是thread命令了 查看程序中有多少线程使用Infothreads 进入到某个线程的内部使用thread count 这样就可以进入到count线程的内部 线程调试中用的最多的还有就是bt命令 这个
  • Python 数据分析1:三种工具实现连接、读取MySQL数据库并处理MySQL数据为DataFrame

    文章目录 一 前言 二 通过 pymysql 获取 MySQL 数据 2 1 连接数据库 2 2 读取数据 2 3 处理数据 三 通过 mysqlclient 获取 MySQL 数据 四 通过 SQLAlchemy 获取 MySQL 数据
  • protobuf-IOS简单总结(编译、环境搭建)

    什么是protobuf Protocol Buffers are a way of encoding structured data in an efficient yet extensible format Google uses Pro
  • 用Vue的三种方法实现加减乘除运算

    js插件 vue js 教程 首先在工具内引入vue js 然后在body里面创建一个div并设置id 我这里给id命名为 app div 在id命名为 app 的div内使用input标签和select标签来设置运算框 第一种comput
  • 多个接口请求出现报错,提示会连续出现多个,如何只弹出一个提示

    场景 如果出现网络问题或者token失效 刷新页面 如果有多个接口请求就会出现报错 那么提示就会连续弹出几个 如图 使用的是vue element ui 解决方法 重写一了个message import Message from eleme
  • 爬虫实例九 豆瓣电影详情信息

    from bs4 import BeautifulSoup 网页解析 获取数据 import re 正则提取 import urllib request urllib error 制定url 获取网页数据 import xlwt 进行exc
  • TensorFlow的GPU版本安装

    建议可以使用anaconda创建专门的虚拟环境来安装TensorFlow 因为如果你之后继续在此环境下安装如tensorflow federated 联邦机器学习 的话就会出问题 1 版本准备 注意四个版本是一一对应的 可能改变任何一个的版
  • 程序猿面试必背——Java资料整理

    程序猿面试必背 适用于 Java开发工程师 后台开发工程师 软件开发工程师 写在前面 秋招已结束 以下是对我帮助比较大的资料 分享一下 可能涉及到的知识点 编程语言 Java 基础知识 计算机网络 操作系统 linux 数据库 关系型如my
  • git bash 风格调整

    在用户目录下有一个 C Users minttyrc文件 用文本方式打开文件 将系统配置加入进去即可全局修改git bash的风格 当然也可以在git bash上右击选择options进行修改 个人配置内容如下 参考 Font Consol
  • 创建基于vite的vue项目

    目录 一 环境 安装Node js 安装yarn工具 二 创建项目 三 项目目录梳理 项目初始目录结构 项目加载过程 四 集成UI组件库vant 配置按需加载Vant 使用组件 引入函数组件的样式 五 集成UI组件库NutUI 配置按需加载
  • github 如何

    链接 https www zhihu com question 20393785 answer 105370502 来源 知乎 著作权归作者所有 商业转载请联系作者获得授权 非商业转载请注明出处 原谅我只会用命令行 还是给一个使用命令行的方
  • 详解vant组件应用于Vue2

    目录 1 安装 1 1 npm安装 1 2 CDN安装 1 3 利用脚手架安装 1 3 1 安装脚手架 没有安装脚手架的 1 3 2 利用脚手架创建程序 1 3 3 使用vue ui进行依赖的安装 1 3 4 依赖安装 2 引入组件 2 1
  • express框架的基本使用

    1 引入express const express require express 2 创建应用对象 const app express 3 创建路由规则 request请求报文的封装 response响应报文的封装 app get req
  • C++的float类型数比较问题

    2020 8 17更新了一下 看到了两个float数比较的 不是0值 也加进了最末尾 相等比较 之前刷题做到一道题 看到题解很奇怪 计算一个数字的立方根 getCubeRoot double input 题解采用了二分法 但比较时并不是用直