浮点数详解

目录

1.概述

2.浮点数的编码方式

2.1.float类型的IEEE编码

2.2.double类型的IEEE编码

2.3.现场问题

2.4.总结


1.概述

        计算机也需要运算和存储数学中的实数。在计算机的发展过程中,曾产生过多种存储实数的方式,有的现在已经很少使用了。不管如何存储,都可以将其划分为定点实数存储方式和浮点实数存储方式两种。所谓定点实数,就是约定整数位和小数位的长度,比如用4字节存储实数,我们可以约定两个高字节存放整数部分,两个低字节存储小数部分。这样做的好处是计算效率高,缺点也显而易见:存储不灵活,比如我们想存储65536.5,由于整数的表达范围超过了2字节,就无法用定点实数存储方式了。对应地,也有浮点实数存储方式,道理很简单,就是用一部分二进制位存放小数点的位置信息,我们可以称之为“指数域”,其他的数据位用来存储没有小数点时的数据和符号,我们可以称之为"数据域" "符号域"。在访问时取得指数域,与数据域运算后得到真值,如67.625,利用浮点实数存储方式,数据域可以记录为67625,小数点的位置可以记为10的-3次方,对该数进行访问时计算一下即可。浮点实数存储方式的优缺点和定点实数存储方式的正好相反。在80286之前,程序员常常为实数的计算伤脑筋,而后来出现的浮点协处理器,可以协助主处理器分担浮点运算程序员计算实数的效率因此得到提升,于是浮点实数存储方式也就普及开来,成为现在主流的实数存储方式。但是,在一些条件恶劣的嵌入式开发场合,仍可看到定点实数的存储和使用。
        在 C/C++中,使用浮点方式存储实数,用两种数据类型来保存浮点数: foat(单精度)和double(双精度)。float在内存中占4字节,double在内存中占8字节。由于占用空间大,double可描述的精度更高。这两种数据类型在内存中同样以十六进制方式存铺,但写大类型有所不同。
        整型类型是将十进制转换成二进制保存在内存中,以十六进制方式显示。浮点类型并不是将一个浮点小数直接转换成二进制数保存,而是将浮点小数转换成的二进制码重新编码,再进行存储。C/C++的浮点数是有符号的。
        在C/C++中,将浮点数强制转换为整数时,不会采用数学上四舍五人的方式,而是食弃掉小数部分,不会进位。
        浮点数的操作不会用到通用寄存器,而是会使用浮点协处理器的浮点寄存器,专门对浮点数进行运算处理。

2.浮点数的编码方式

        浮点数编码转换采用的是IEEE 规定的编码标准,float 和 double 这两种类型数据的转换原理相同,但由于表示的范围不一样,编码方式有些许区别。IEEE规定的浮点数编码会将一个浮点数转换为二进制数。以科学记数法划分,将浮点数拆分为3部分:符号、指数、尾数。

2.1.float类型的IEEE编码

        foat类型在内存中占4字节(32位)。最高位用于表示符号,在剩余的31位中,从左向右取8位表示指数,其余表示尾数,如下图所示。

76789abd6c2a47ad93b749a2f3bcc3f6.png
        在进行二进制转换前,需要对单精度浮点数进行科学记数法转换。例如,将foat类型的12.25f转换为IEEE编码,须将12.25f转换成对应的二进制数1100.01,浮点数转二进制的方法为:二进制表示整数时,最低位代表2的0次方,往高位依次是2的1次方,2次方,3次方……那么对应的,二进制数小数点后面,最高位则是2的-1次方,-2次方,-3次方……如下图所示:

        举几个例子:

        那么12.25f转换成对应的二进制数的整数部分为1100,小数部分为01;小数点向左移动,每移动1次,指数加1,移动到除符号位的最高位为1处,停止移动,这里移动3次。对12.25f进行科学记数法转换后二进制部分为1.10001,指数部分为 3。在IEEE 编码中,由于在二进制情况下,最高位始终为1,为一个恒定值,故将其忽略不计。这里是一个正数,所以符号位添加0。
        12.25f经 IEEE 转换后各位如下。
        1)符号位:0
        2)指数位:十进制 3+127=130,转换为二进制为10000010。
        3)尾数位:10001000000000000000000(当不足23位时,低位补0填)。

        由于尾数位中最高位1是固定值,故忽略不计,只要在转换回十进制数时加1即可。为什么指数位要加 127呢?这是因为指数可能出现负数,十进制数 127 可表示为二进制数01111111,IEEE编码方式规定,当指数小于0111111时为一个负数,反之为正数,因01111111为0
        将示例中转换后的符号位、指数位和尾数位按二进制拼接在一起,就成为一个完整的IEEE 浮点编码:01000001010001000000000000000000。转换成十六进制数为0x41440000内存中以小端方式进行排列,故为 00004441,分析结果如下图所示。 2ec9d132f26b4dbe9af83f805987bce4.png

        使用第三方工具软件计算更清楚更简便,如下图所示:

aa6690950d3b4ff1b8b9396a73bb5299.png

        上面演示了符号位为正、指数位也为正的情况。那么什么情况下指数位可以为负呢?根据科学记数法,小数点向整数部分移动时,指数做加法。相反,小数点向小数部分移动时,指数需要以0起始做减法。浮点数-0.125f转换EEE编码后,将会是一个符号位为1、指数部分为负的数。-0.125f经转换后二进制部分为0.001,用科学记数法表示为1.0,指数为 -3。
        -0.125fIEEE 转换后各位的情况如下。
        1)符号位:1。
        2)指数位:十进制 127+(-3 ),转换为二进制是 01111100,如果不足8位,则高位补 0。
        3)尾数位:00000000000000000000000。

        -0.125f转换后的 IEEE 编码二进制拼接为 10111110000000000000000000000000。转换成十六进制数为 0xBE000000,内存中显示为00 00 00 BE,分析结果如下图所示。

006985ecf4b94acfa729146129c5608c.png

        使用第三方工具软件计算更清楚,如下图所示: 

b0b093a22ca347c699bd58a4cc0af742.png

        上面的两个浮点数小数部分转换为二进制时都是有穷的,如果小数部分转换为二进时得到一个无穷值,则会根据尾数部分的长度舍弃多余的部分。如单精度浮点数1.3f,数部分转换为二进制就会产生无穷值,依次转换为0.3、0.6、1.2、0.4、0.8、1.6、1.2、00.8……转换后得到的二进制数为 1.01001100110011001100110,到第23 位终止,尾数部分无法保存更大的值。

        1.3f经 EEE 转换后各位的情况如下:
        1)符号位:0。
        2)指数位:十进制 0+127,转换二进制01111111。
        3)尾数位:01001100110011001100110。

        1.3f转换后的IEEE编码二进制拼接为00111111101001100110011001100110。转换十六进制数为0x3FA66666,在内存中显示为66 66 A6 3F。由于在转换二进制过程中产些了无穷值,舍弃了部分位数,所以进行IEEE编码转换后得到的是一个近似值,存在一定的误差。再次将这个IEEE编码值转换成十进制小数,得到的值为12516582,四合五人保留位小数之后为1.3。这就解释了为什么C++在比较浮点数值是否为0时,要做一个区同中较而不是直接进行等值比较。正确浮点数比较如下代码:

float f1=0.0001f;
if(f2 >=-f1 6& f2 <= f1)
{
    // f1等于0
}

2.2.double类型的IEEE编码

        前文讲解了单精度浮点类型的IEEE编码。double类型和 foat类型大同小异,只是double类型表示的范围更大,占用空间更多,是 foat类型所占空间的两倍。当然,精准度double 类型占8字节的内存空间,同样,最高位也用于表示符号,指数位占11位,剩也会更高。
        在 float类型中,指数位范围用8位表示,加127后用于判断指数符号。在double类型余 52 位表示位数。中,由于扩大了精度,因此指数范围使用11位正数表示,加1023 后可用于指数符号判断。double 类型的 IEEE 编码转换过程与 foat 类型一样,读者可根据 foat类型的转换流程来转换 double类型,此处不再赘述。

2.3.现场问题

        通过上面的讲解,我们知道浮点数是有可能出现经过IEEE编码转换后得到的是一个近似值,跟实际值存在一定的偏差。项目前期制定的设备两端通信协议设计某些字段为double类型,导致采集数据设备采集到的两端的二进制数据不一致的问题。后期调整,全部把double类型的数据转换为整数进行传输,才保证了两端二进制数据的一致性。

2.4.总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注本博客的其它内容。

参考:

浮点数与十六进制转换工具下载地址:https://download.csdn.net/download/haokan123456789/88771127?spm=1001.2014.3001.5501   浮点类型(float、double)在内存中如何存储?-腾讯云开发者社区-腾讯云
C++:float型数据存储原理及精度丢失溢出深入解析 - 知乎

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HDMI、VGA、DVI、DB接口的区别

HDMI、VGA、DVI和DB&#xff08;也称为DisplayPort&#xff09;是不同类型的视频接口标准&#xff0c;它们用于连接计算机、显示器、电视和其他视频设备。 HDMI&#xff08;High-Definition Multimedia Interface&#xff0c;高清晰度多媒体接口&#xff09;&#xff1a;HDMI支…

JavaEE进阶(6)SpringBoot 配置文件(作用、格式、properties配置文件说明、yml配置文件说明、验证码案例)

接上次博客&#xff1a;JavaEE进阶&#xff08;5&#xff09;Spring IoC&DI&#xff1a;入门、IoC介绍、IoC详解&#xff08;两种主要IoC容器实现、IoC和DI对对象的管理、Bean存储、方法注解 Bean)、DI详解&#xff1a;注入方式、总结-CSDN博客 目录 配置文件作用 Sprin…

MySQL定期整理磁盘碎片

MySQL定期整理磁盘碎片&#xff1a;提升数据库性能的终极指南 MySQL作为一个强大的关系型数据库管理系统&#xff0c;在长时间运行后可能会产生磁盘碎片&#xff0c;影响数据库性能。本博客将深入讨论如何定期整理MySQL磁盘碎片&#xff0c;以确保数据库的高效运行。我们将介绍…

nexus清理docker私库

下载nexus-cli客户端&#xff0c;并非必须下载到服务器&#xff0c;理论上只要能访问到nexus就行 wget https://s3.eu-west-2.amazonaws.com/nexus-cli/1.0.0-beta/linux/nexus-cli这个链接下载不了了&#xff0c;末尾有资源下载&#xff0c;里面包含了完整包和脚本&#xff0…

风二西CTF流量题大集合-刷题笔记|NSSCTF流量题(1)

2.[鹤城杯 2021]流量分析 flag{w1reshARK_ez_1sntit} 3.[CISCN 2023 初赛]被加密的生产流量 c1f_fi1g_1000 4.[GKCTF 2021]签到 flag{Welc0me_GkC4F_m1siCCCCCC!} 5.[闽盾杯 2021]Modbus的秘密 flag{HeiDun_2021_JingSai} 6.[LitCTF 2023]easy_shark 7.[CISCN 2022 初赛]ez…

最新AI系统ChatGPT网站系统源码,支持AI绘画,GPT语音对话,ChatFile文档对话总结,DALL-E3文生图,MJ绘画局部编辑重绘

一、前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图文教程吧。已支持GPT…

MYSQL之索引语法与使用

索引分类 分类 含义 特点 关键字 主键索引 针对表中主键创建的索引 默认自动创建&#xff0c;只能有一个 PRIMARY 唯一索引 …

L1-095 分寝室(Java)

学校新建了宿舍楼&#xff0c;共有 n 间寝室。等待分配的学生中&#xff0c;有女生 n0 位、男生 n1 位。所有待分配的学生都必须分到一间寝室。所有的寝室都要分出去&#xff0c;最后不能有寝室留空。 现请你写程序完成寝室的自动分配。分配规则如下&#xff1a; 男女生不能混…

AI对比:ChatGPT和文心一言的区别和差异

目录 一、ChatGPT和文心一言大模型的对比分析 1.1 二者训练的数据情况分析 1.2 训练大模型数据规模和参数对比 1.3 二者3.5版本大模型对比总结 二、ChatGPT和文心一言功能对比分析 2.1 二者产品提供的功能情况分析 2.2 测试一下各种功能的特性 2.2.1 文本创作能力 2.2…

分布式一致性算法---Raft初探

读Raft论文也有一段时间了&#xff0c;但是自己总是以目前并没有完全掌握为由拖着这篇博客。今天先以目前的理解程度&#xff08;做了6.824的lab2A和lab2B&#xff09;对这篇论文做一个初步总结&#xff0c;之后有了更深入的理解之后再进行迭代&#xff0c;关于本文有任何疑问欢…

【数据结构和算法】--- 二叉树(3)--二叉树链式结构的实现(1)

目录 一、二叉树的创建(伪)二、二叉树的遍历2.1 前序遍历2.2 中序遍历2.3 后序遍历 三、二叉树节点个数及高度3.1 二叉树节点个数3.2 二叉树叶子节点个数3.3二叉树第k层节点个数3.4 二叉树查找值为x的节点 四、二叉树的创建(真) 一、二叉树的创建(伪) 在学习二叉树的基本操作前…

vertica10.0.0单点安装_ubuntu18.04

ubuntu的软件包格式为deb&#xff0c;而rpm格式的包归属于红帽子Red Hat。 由于项目一直用的vertica-9.3.1-4.x86_64.RHEL6.rpm&#xff0c;未进行其他版本适配&#xff0c;而官网又下载不到vertica-9.3.1-4.x86_64.deb&#xff0c;尝试通过alian命令将rpm转成deb&#xff0c;但…

【GitHub项目推荐--Git 教程】【转载】

本开源项目是 Will 保哥在 2013 第 6 界 IT 邦帮忙铁人赛年度大奖的得奖著作。这是一个 Git 教程&#xff0c;这个开源教程用 30 天的时间&#xff0c;带领大家详细了解使用 Git 。 重点介绍了 Git 的一些常用操作&#xff0c;以及日常工作中实际应用场景讲解&#xff0c;下图…

让二叉树无处可逃

志不立&#xff0c;天下无可成之事。 ——王阳明 二叉树 1、树&#xff1f;什么是树1、1、基本概念1、2、树的相关概念1、3、树的表示方式1、4、树的实际运用 2、二叉树&#xff1f;只有两个分支吗&#xff1f;2、1、基本概念2、2、二叉树的相关定义2、3、二叉树的相关性质2、4…

Dockerfile-xxxx

1、Dockerfile-server FROM openjdk:8-jdk-alpine WORKDIR /app COPY . . CMD java -Xms1536M -Xmx1536M -XX:UseG1GC -jar -Dlog4j2.formatMsgNoLookupstrue -Dloader.pathresources,lib -Duser.timezoneGMT-05 /app/server-main-1.0.0.jar 2、Dockerfile-bgd #FROM openjdk…

一站式社交媒体管理:揭秘HubSpot的全面解决方案

在当今数字化时代&#xff0c;社交媒体已经成为企业推广和品牌塑造的关键渠道。而HubSpot作为一站式市场营销平台&#xff0c;不仅致力于协助企业实现综合市场目标&#xff0c;更在社交媒体管理领域提供了全面解决方案。今天运营坛将深入探讨HubSpot如何成为一站式社交媒体管理…

DAY08_SpringBoot—整合Mybatis-Plus

目录 1 MybatisPlus1.1 MP介绍1.2 MP的特点1.3 MybatisPlus入门案例1.3.1 导入jar包1.3.2 编辑POJO对象1.3.3 编辑Mapper接口1.3.4 编译YML配置文件1.3.5 编辑测试案例 1.4 MP核心原理1.4.1 需求1.4.2 原理说明1.4.3 对象转化Sql原理 1.5 MP常规操作1.5.1 添加日志打印1.5.2 测…

哪个牌子的洗地机质量好?值得入手的洗地机

在家庭清洁方面&#xff0c;洗地机绝不是被认为的智商税。实际上&#xff0c;洗地机是一种非常实用的清洁工具&#xff0c;其最大的优点在于能够高效地协助我们清理家居环境&#xff0c;不论是在何种场景下&#xff0c;都能有效提升卫生水平。然而&#xff0c;由于市场上存在众…

seata1.8 + nacos,store.mode=db

吐槽一下&#xff0c;官方文档是真少&#xff0c;而且更新很不及时。。 官网地址&#xff1a;直接部署 | Apache Seata 上述地址也包含了下载链接&#xff0c;我用的1.8版本&#xff0c;挑一些关键配置说一下 1、服务器上&#xff0c;seata/conf/application.yml&#xff0c;将…

【数据结构】从顺序表到ArrayList类

文章目录 1.线性表1.1线性表的概念2.顺序表2.1顺序表的概念2.2顺序表的实现2.3接口的实现(对数组增删查改操作)3.ArrayList简介4. ArrayList使用 4.1ArrayList的构造4.2 ArrayList的方法4.3 ArrayList的遍历 1.线性表 1.1线性表的概念 线性表&#xff08;linear list&#xf…
最新文章