浮点型在内存中的存储 浮点型如何取出 IEEE754 SME 精度丢失 C语言进阶

2023-10-23 13:50

本文主要是介绍浮点型在内存中的存储 浮点型如何取出 IEEE754 SME 精度丢失 C语言进阶,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

作者的话
本文涵盖了浮点型在内存中的如何存储、如何取出、为何有精度丢失等知识点~


浮点型概括

常见的浮点型数据有三种:

  1. 以科学计数法表示的:1e10、1.28e10
  2. 数据后加入字符‘f’的:3.14f、7.76f
  3. 不用科学计数法也不加f:1.22、4.89

第一种表示:
1*10^10 和 1.28*10^10
第二种表示:
用float创建的浮点数,要在后面加’f’,不然会默认为double型储。
第三种表示:
用double创建的浮点数,或没加‘f’的float创建数。


浮点数的存储

根据国际标准IEEE754规定,任意的浮点数V都可以表示为以下形式:

  • V=(-1)^S * M * 2^E
  • S等于0或1,是-1的指数位,0则正数,1则负数
  • M等于有效数字,应大于1,小于2
  • E是2的指数位,是一个有范围的正数

例:

  1. V=5.5
  2. V=9.0

首先我们要知道,十进制的小数点右边第一位,表示10的-1次方,同样,二进制的小数点后一位,是表示2的-1次方
则V=5.5可以分解成:101.1
则V=9.0可以分解成:1001.0
随后,将这个分解后的数字转为大于1,小于2的数,并将小数点移动了几位记下来,这将是E的大小

  1. V=1.011,移动2位,E=2
  2. V=1.001,移动3位,E=3

最后,如果是正数,S为0,如果是负数,S为1。

  1. V=(-1)^0 * 1.011 * 2^2
  2. V=(-1)^0 * 1.001 * 2^3

这样,你就知道如何表示一个浮点型的数了,由此可见,一个浮点型的数,其大小只与>S、M、E三个变量有关,所以在内存中对于浮点型的存储,只需要存储这三个变量可。


bit位储存模型

在这里插入图片描述
在这里插入图片描述

  • 第一张图:float的储存模型
  • 第二张图:double的储存模型
  • 图片来自比特科技

这两张图相信以各位的聪明才智,不需过多解释也能看得懂。

我们知道,M是一个大于1,小于2的数,那么不同的M之间只有小数点后面的数不同,如果我们只把M小数点后面的数存起来,取出的时候再加上1,就可以多存一位。
因此,float的M能存24位,double的M能存53位。

此外,对于E的存储,还有一些别的规定:

因为E是一个无符号的数,只能是正数,但是科学计数法中是可以出现负数的,所以IEEE又规定,E在存入时必须加上一个中间值

  • 对于float,E有8位,取值范围为0~255,存入时需加上255/2=127.
  • 对于double,E有11位,取值范围为0~2047,存入时需加上2047/2=1023.

比如:5.5的E是2,存入时需存2+127=129;9.0的E是3,存入时需存3+127=130.


精度丢失

上述我们说到,二进制小数点后1位是2的-1次方,后2位是2的-2次方…

即,一个浮点型的小数点后面的数,只能用0.5、0.25、0.125…等等数来拼凑起来。

若是我给一个3.141592653579,这在有限的M位下是不可能完整精确地拼凑起来的,于是就有了精度丢失
在这里插入图片描述
Look:我把3.14存进a,鼠标放在上面,显示这个数并不是精准的3.14.

这也是为什么,double型能存的数据比float型更为精准。(因为M位更多)


浮点型的取出

  • S的取出:没什么好说的,是1还是1,是0还是0.
  • M的取出:因为只存了小数点后面,取出来后要加上1.
  • E的取出:又分为三种情况,请看细细道来。

1,E全为1,此时若M全是0,则是无穷大,正负看S;若M不全是0,则这个数是NaN(未定义或不可表示的值),至于为什么,我只能说这是未尽事宜,是规定。

2,E全为0,这种情况下在取出E时,float规定E为-126,double规定E为-1022,M取出来后不再加上1,以此来表示一个无限接近于0的数,正负看S。

3,E不全0也不全1,减去127或1023拿出来即可。


浮点数的取出实机演示

在这里插入图片描述
如图,我将5.5f存入a;
在这里插入图片描述
随后,取a的地址进行观察。
因为我当前环境是x86,机器为小端存储。

PS:如果您不明白什么是小端存储,请点击:大小端字节序存储详解

所以a的地址存放的十六进制序列为:40B00000
转换为二进制:0 10000001 01100000000000000000000
观察S、M、E的位置
S:0
E:因为不全是1或全是0,应减去127,0b10000001-127=2
M:0.011+1=1.011
这样,你就把V取出来了。
这时候有同学可能要问了,这把SME三个数装上以后,是1.011*2^2是4.011啊。

请注意:此时是用二进制表示


这篇关于浮点型在内存中的存储 浮点型如何取出 IEEE754 SME 精度丢失 C语言进阶的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/268266

相关文章

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

异构存储(冷热数据分离)

异构存储主要解决不同的数据,存储在不同类型的硬盘中,达到最佳性能的问题。 异构存储Shell操作 (1)查看当前有哪些存储策略可以用 [lytfly@hadoop102 hadoop-3.1.4]$ hdfs storagepolicies -listPolicies (2)为指定路径(数据存储目录)设置指定的存储策略 hdfs storagepolicies -setStoragePo

HDFS—存储优化(纠删码)

纠删码原理 HDFS 默认情况下,一个文件有3个副本,这样提高了数据的可靠性,但也带来了2倍的冗余开销。 Hadoop3.x 引入了纠删码,采用计算的方式,可以节省约50%左右的存储空间。 此种方式节约了空间,但是会增加 cpu 的计算。 纠删码策略是给具体一个路径设置。所有往此路径下存储的文件,都会执行此策略。 默认只开启对 RS-6-3-1024k

NameNode内存生产配置

Hadoop2.x 系列,配置 NameNode 内存 NameNode 内存默认 2000m ,如果服务器内存 4G , NameNode 内存可以配置 3g 。在 hadoop-env.sh 文件中配置如下。 HADOOP_NAMENODE_OPTS=-Xmx3072m Hadoop3.x 系列,配置 Nam

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

科研绘图系列:R语言扩展物种堆积图(Extended Stacked Barplot)

介绍 R语言的扩展物种堆积图是一种数据可视化工具,它不仅展示了物种的堆积结果,还整合了不同样本分组之间的差异性分析结果。这种图形表示方法能够直观地比较不同物种在各个分组中的显著性差异,为研究者提供了一种有效的数据解读方式。 加载R包 knitr::opts_chunk$set(warning = F, message = F)library(tidyverse)library(phyl

透彻!驯服大型语言模型(LLMs)的五种方法,及具体方法选择思路

引言 随着时间的发展,大型语言模型不再停留在演示阶段而是逐步面向生产系统的应用,随着人们期望的不断增加,目标也发生了巨大的变化。在短短的几个月的时间里,人们对大模型的认识已经从对其zero-shot能力感到惊讶,转变为考虑改进模型质量、提高模型可用性。 「大语言模型(LLMs)其实就是利用高容量的模型架构(例如Transformer)对海量的、多种多样的数据分布进行建模得到,它包含了大量的先验

[MySQL表的增删改查-进阶]

🌈个人主页:努力学编程’ ⛅个人推荐: c语言从初阶到进阶 JavaEE详解 数据结构 ⚡学好数据结构,刷题刻不容缓:点击一起刷题 🌙心灵鸡汤:总有人要赢,为什么不能是我呢 💻💻💻数据库约束 🔭🔭🔭约束类型 not null: 指示某列不能存储 NULL 值unique: 保证某列的每行必须有唯一的值default: 规定没有给列赋值时的默认值.primary key:

【Linux 从基础到进阶】Ansible自动化运维工具使用

Ansible自动化运维工具使用 Ansible 是一款开源的自动化运维工具,采用无代理架构(agentless),基于 SSH 连接进行管理,具有简单易用、灵活强大、可扩展性高等特点。它广泛用于服务器管理、应用部署、配置管理等任务。本文将介绍 Ansible 的安装、基本使用方法及一些实际运维场景中的应用,旨在帮助运维人员快速上手并熟练运用 Ansible。 1. Ansible的核心概念

Flutter 进阶:绘制加载动画

绘制加载动画:由小圆组成的大圆 1. 定义 LoadingScreen 类2. 实现 _LoadingScreenState 类3. 定义 LoadingPainter 类4. 总结 实现加载动画 我们需要定义两个类:LoadingScreen 和 LoadingPainter。LoadingScreen 负责控制动画的状态,而 LoadingPainter 则负责绘制动画。