IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 深入C语言三种类型(float/bool/指针)与“零值“的比较 -> 正文阅读

[C++知识库]深入C语言三种类型(float/bool/指针)与“零值“的比较

目录

float类型与"零值"的比较

浮点数的存储

精度

关于需不需要取等号

Bool(布尔)类型与"零值"的比较

深入理解C 中 bool

C中bool 值与0的比较

指针类型与"零值"的比较

如何理解类型转化

指针与0的比较


float类型与"零值"的比较

浮点数的存储

浮点数在内存中存储,并不想我们想的是完整存储的
在十进制转化成为二进制,是有可能有精度损失的
注意
这里的损失,不是一味的减少了,还有可能增多
浮点数本身存储的时候,在计算不尽的时候,会 四舍五入 或者其他策略
int main()
{
double x = 3.6;
printf("%.50f\n", x);
system("pause");
return 0;
}

int main() 
{ 
 double x = 1.0;
 double y = 0.1;
 printf("%.50f\n", x - 0.9);
 printf("%.50f\n", y);
 if ((x - 0.9) == y)
{
 printf("you can see me!\n");
 }
else
{
printf("oops\n");
 }
system("pause");
 return 0;
 }

?结论:因为精度损失问题,两个浮点数,绝对不能使用==进行相等比较

?解决方案:进行范围精度比较

//伪代码 
if((x-y) > -精度 && (x-y) < 精度)
{
 //TODO
}
//伪代码-简洁版 
if(fabs(x-y) < 精度)
{//fabs是浮点数求绝对值
//TODO
}

精度

自己设置?后面如果有需要,可以试试,通常是宏定义

使用系统精度?暂时推荐

#include<float.h> //使用下面两个精度,需要包含该头文件 
DBL_EPSILON //double 最小精度 
FLT_EPSILON //float 最小精度 
//代码调整后 
#include <stdio.h> 
#include <math.h> //必须包含math.h,要不然无法使用fabs 
#include <float.h> //必须包含,要不然无法使用系统精度 
#include <windows.h> 
int main() 
{ 
 double x = 1.0;
 double y = 0.1;
 printf("%.50f\n", x - 0.9);
 printf("%.50f\n", y);
 if (fabs((x - 0.9) - y) < DBL_EPSILON)
{ //原始数据是浮点数,我们就用DBL_EPSILON 
 printf("you can see me!\n");
}
 else
{
 printf("oops\n");
}
 system("pause");
 return 0; }

定义

//两个精度定义 
#define DBL_EPSILON 2.2204460492503131e-016 /* smallest such that 1.0+DBL_EPSILON != 1.0 */ 

#define FLT_EPSILON 1.192092896e-07F /* smallest such that 1.0+FLT_EPSILON != 1.0 */
XXX_EPSILON 是最小误差 , 是: XXX_EPSILON + n 不等于 n 的最小的正数。
EPSILON 这个单词翻译过来是 'ε' 的意思,数学上,就是极小的正数 ---- 来自百度?
//最终代码 
#include <stdio.h> 
#include <math.h> 
#include <float.h> 
#include <windows.h> 
int main() 
{
 double x = 0.00000000000000000000001;
 //if (fabs(x-0.0) < DBL_EPSILON){ //写法1 
//if (fabs(x) < DBL_EPSILON){ //写法2 
if(x > -DBL_EPSILON && x < DBL_EPSILON)
{ //书中写法
 printf("you can see me!\n");
 }
else
{
 printf("oops\n");
}
 system("pause");
 return 0; }

关于需不需要取等号

x > -DBL_EPSILON && x < DBL_EPSILON: 为何不是>= && <= 呢?

个人看法:XXX_EPSILON是最小误差,是:XXX_EPSILON+n不等于n的最小的正数

XXX_EPSILON+n不等于n的最小的正数:

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

but,XXX_EPSILON依旧是引起不等的一员

换句话说:

fabs(x) <= DBL_EPSILON(确认x是否是0的逻辑)

如果=,就说明x本身,已经能够引起其他和他+-的数据本身的变化了,这个不符合0的概念

Bool(布尔)类型与"零值"的比较

深入理解C 中 bool

C语言有没有bool类型?

c99之前,主要是c90/c89是没有的

目前大部分书,都是认为没有的

因为书,一般都要落后于行业

但是c99引入了_Bool类型

你没有看错,_Bool就是一个类型

不过在新增头文件stdbool.h中,被重新用宏写成了 bool,为了保证C/C++兼容性

//测试代码1 
#include <stdio.h> 
#include <stdbool.h> //没有这个头文件会报错,使用新特性一定要加上 
#include <windows.h> 
int main()
{ bool ret = false;
 ret = true;
 printf("%d\n", sizeof(ret)); //vs2013 和 Linux中都是1 
system("pause");
 return 0;
 }
//查看源码 
/* stdbool.h standard header */ 
//stdbool.h #ifndef _STDBOOL 
#define _STDBOOL 
#define __bool_true_false_are_defined 1 
#ifndef __cplusplus 
#define bool _Bool //c99中是一个关键字哦,后续可以使用bool
#define false 0 //假 
#define true 1 //真

理论上,表示真假,需要一个bit就够了

不过这个问题,还是要取决于编译器的理解

vs2013中认为是1个字节

but

int main() 
{ //在vs中,光标选中BOOL,单击右键,可以看到转到定义,就能看到BOOL是什么 
 BOOL ret = FALSE;
 ret = TRUE;
 printf("%d\n", sizeof(ret)); //输出结果是4,因为在源代码中,是这么定义的:typedef int BOOL; system("pause");
 return 0;
 }

?这是Microsoft自己搞的一套BOOL值。在vs中转到BOOL对应的头文件,翻到最上面,就能看到微软的版权信息。可以通过编译,但可移植性差。

总结:

1. 优先使用c90,就是我们之前以及后面一直用的方式

2. 万一非得使用bool,推荐c99标准,不推荐MS自定义

C中bool 值与0的比较

int main() 
{ int pass = 0; 
//0表示假,C90,我们习惯用int表示bool 
//bool pass = false;
//C99 if (pass == 0){ //理论上可行,但此时的pass是应该被当做bool看待的,==用来进行整数比较,不推荐 
//TODO
 }
if (pass == false){ //不推荐,尽管在C99中也可行
//TODO 
}
if (pass){ //推荐
 //TODO 
}
//理论上可行,但此时的pass是应该被当做bool看待的,==用来进行整数比较,不推荐
//另外,非0为真,但是非0有多个,这里也不一定是完全正确的
 if (pass != 1){ 
//TODO 
}
if (pass != true){ //不推荐,尽管在C99中也可行 
//TODO 
}
if (!pass)
{ //推荐 
//TODO 
}
system("pause");
return 0;
 }

结论:bool类型,直接判定,不用操作符进行和特定值比较

指针类型与"零值"的比较

如何理解类型转化

示例1:
“123456”(字符)-->>123456(int型)
\\真正的转化:需要编写算法,或使用相关库函数
\\改变内存中的存储的数据

示例2:
11111111111111111111111111111111
signed int(有符号数)-->>unsigned int(无符号数) 
\\强制类型转化:()强制类型转化操作符
\\不改变内存中存储的数据,只改变对应的类型

指针与0的比较

?注:类型一定要对应,避免引起误解

A:看到0,会认为p是int型

C:看到NULL,就会明白p是空指针,是指针类型

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-03 10:58:44  更:2021-08-03 10:59:04 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/9 19:20:47-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码