C++浮点数类型详情

 更新时间:2021年11月03日 10:43:55   作者:Coder_LT  
这篇文章主要介绍了C++浮点数类型,浮点数是C++的第二组基本类型,它能够表示带小数部分的数字。不仅如此,浮点数的范围也比int更大,可以表示更大范围的数字。下面来我们大家一起来学习学习内容

1、浮点数

浮点数是C++的第二组基本类型,它能够表示带小数部分的数字。不仅如此,浮点数的范围也比int更大,可以表示更大范围的数字。

我们都知道在计算机当中,所有数据本质上都是转化成二进制存储的。整数很简单,存储的就是转化成二进制之后的01串,那么浮点数又是如何存储的呢?

很容易猜到的是浮点数存储的结果也是二进制,但相比于整型直接转化成二进制要复杂一些。

它需要先表示成下面这行式子:

这里的n即我们要存储的浮点数,s表示符号位,m是尾数,而e则是阶数。

符号位很好理解,它和整型当中的符号位一样,0表示正数,1表示负数。m表示尾数,。我们这么看很抽象,来看一个例子,比如3.0,转化成二进制是,相当于。那么,。

我们了解了浮点数的表示方式,那么它又是如何存储在计算机当中的呢?这需要我们进一步地剖析其中的细节。

2、关于m

首先是mm被定义成一个大于等于1,小于2的小数。我们可以简单写成1.xx,其中xx表示的就是小数的部分。

既然它总是大于等于1,小于2的,那么它的个位一定是1,我们就可以将它省略,仅仅看之后小数的部分。小数的部分,我们同样使用二进制来逼近。比如0.625,可以表示成0.5 + 0.125,即,表示成二进制就是,只不过这里它的最高位是从-1开始的。

以32位的浮点数为例,除去1位表示符号,8位表示阶数之后,还有23位留给m。由于我们舍掉了小数点之前的1,所以我们的阶数是从-1开始的,理论上等价于24个二进制位。

3、关于e

在浮点数存储当中,e是一个无符号整数。以32位浮点数为例,e一共有8位,可以表示0-255。

但e是可以为负数的,根据IEEE 754的规定,e的真实值必须再减去一个中间数。对于8位的e,它的中间数是127。比如e的实际值是10,但是存储的时候需要存储成127+10=137

除此之外,e还有另外三种情况:

  • e不全为0,或全为1时,采用上述的规则表示
  • e全为0时,e等于1-127,有效数字m不再默认加上1,这样是为了还原0.xxx的小数,以及接近于0的数
  • e全为1时,如果有效数字m全为0,表示无穷大,如果m不全为0,表示nan(not a number)

关于e的规则看起来有些复杂,初看觉得有些难以理解,为什么要用减去中间值的设计,而不用符号位?后来仔细思考了一下才发现,如果引入符号位很难区分0.xxx以及e就是等于0的情况,虽然也可以特判处理,但就没有现在这样优雅了。

觉得上文看不懂的小伙伴可以直接略过这段,毕竟这个是浮点数的实现原理,算是很底层的内容了,C++ primer上对于这部分也没有过多阐述。

4、浮点数的使用

C++当中有两种浮点数的书写方式,第一种是使用常规的小数点表示法:

double a = 1.23;
float b = 3.43;


另外一种写法是科学记数法,写成:

double a = 2.45e8;
double b = 1e-7;


2.45e8表示,e之后可以跟正数也可以跟负数,但数字当中不能有空格。

5、浮点数类型

和C语言一样,C++也有三种浮点数类型:float,doublelong double。和整型一样,这三种类型都是浮点数,只不过表示的范围不同。

浮点数的范围有两个部分综合决定,一个部分是有效数字。比如14179是5位有效数字,而14000只有两位,因为后面三个0都是填充位,有效数字的位数不依赖小数点的位置。C++当中要求,float通常表示7位有效数字,double通常16位位,而long double至少和double一样。

另外,它们能够表达的指数范围至少是-37到37。一般来说,float一共是4个字节32位,而double是8个字节64位,当然这也取决于具体的运行环境。

6、注意事项

关于浮点数的使用有几点注意事项,千万要注意。

  • cout输出浮点数会删除结尾的0
  • 书写浮点数常量时默认为double类型,如果需要强制表示为float类型,请在结尾加上后缀f或者F,如:2.34f
  • 由于浮点数有精度,不能直接判断两个浮点数是否相等,很有可能得不到预期结果,正确的做法是判断精度范围,

如:

double epsilon = 1e-8;
// 判断a是否和b相等
if (abs(a - b) < epsilon) {
    // todo
}

判断两个浮点数a和b是否相等,等价于两者的差的绝对值小于某一个精度。

范围问题,如运行下列代码将得到错误的结果:

float a = 2.3e22f;
float b = a + 1.0f;

cout << b - a << endl;

输出的结果将是0,因为2.3e22是一个小数点左边有23位的数字,加上1之后,就是在第23位加上1。但是float类型只能表示数字中的前6位或者前7位,表示不了这么高的精度,因此这个+1的操作完全没有生效。

这个问题是一个大坑,一不小心就会中招,千万要小心。

到此这篇关于C++浮点数类型详情的文章就介绍到这了,更多相关C++浮点数类型内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

注:文章转自微信众号:Coder梁(ID:Coder_LT)

相关文章

  • C语言数据结构之二叉树的非递归后序遍历算法

    C语言数据结构之二叉树的非递归后序遍历算法

    这篇文章主要介绍了C语言数据结构之二叉树的非递归后序遍历算法的相关资料,希望通过本文能帮助到大家,让大家实现这样的功能,需要的朋友可以参考下
    2017-10-10
  • C++中的explicit关键字实例浅析

    C++中的explicit关键字实例浅析

    在C++程序中很少有人去使用explicit关键字,不可否认,在平时的实践中确实很少能用的上,再说C++的功能强大,往往一个问题可以利用好几种C++特性去解决。接下来给大家介绍 C++中的explicit关键字,需要的朋友可以参考下
    2017-03-03
  • ​​​​​​​C语言实现单链表基本操作方法

    ​​​​​​​C语言实现单链表基本操作方法

    这篇文章主要介绍了​​​​​​​C语言实现单链表基本操作方法,文章围绕主题展开详细介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-05-05
  • 数据结构之带头结点的单链表

    数据结构之带头结点的单链表

    单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:数据域(数据元素的映象) + 指针域(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据
    2023-07-07
  • C语言字符串的模式匹配之BF与KMP

    C语言字符串的模式匹配之BF与KMP

    这篇文章记录一下串里面的模式匹配,模式匹配,顾名思义就是给定一个被匹配的字符串,然后用一个字符串模式(模型)去匹配上面说的字符串,看后者是否在前者里面出现。常用的有2种算法可以实现,下面我们来具体探讨下
    2021-09-09
  • C++ OpenGL实现旋转立方体的绘制

    C++ OpenGL实现旋转立方体的绘制

    这篇文章主要主要为大家详细介绍了如何利用C++和OpenGL实现旋转立方体的绘制,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起动手尝试一下
    2022-07-07
  • 用C语言如何打印一个等腰三角形

    用C语言如何打印一个等腰三角形

    这篇文章主要介绍了用C语言如何打印一个等腰三角形,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • C++结构体数组实现贪吃蛇

    C++结构体数组实现贪吃蛇

    这篇文章主要为大家详细介绍了C++结构体数组实现贪吃蛇,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-03-03
  • C语言每日练习之字符串反转

    C语言每日练习之字符串反转

    这篇文章主要介绍了C语言字符串反转,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-11-11
  • 解析ActiveMQ的使用说明总结

    解析ActiveMQ的使用说明总结

    本篇文章是对ActiveMQ的使用进行了详细的分析介绍,需要的朋友参考下
    2013-05-05

最新评论