【数据的存储】浮点数在内存中的存储详解【超详细的保姆级别教程,让面试官心服口服】手撕浮点数存储使用方式
【数据的存储】浮点数在内存中的存储详解【超详细的保姆级别教程,让面试官对你心服口服】手撕浮点数存储使用方式
作者: @小小Programmer
这是我的主页:@小小Programmer
在食用这篇博客之前,博主在这里介绍一下其它高质量的编程学习栏目:
数据结构专栏:数据结构 这里包含了博主很多的数据结构学习上的总结,每一篇都是超级用心编写的,有兴趣的伙伴们都支持一下吧!
算法专栏:算法 这里可以说是博主的刷题历程,里面总结了一些经典的力扣上的题目,和算法实现的总结,对考试和竞赛都是很有帮助的!
先赞后看好习惯 打字不容易,这都是很用心做的,希望得到支持你 大家的点赞和支持对于我来说是一种非常重要的动力。看完之后别忘记关注我哦!️️️
本篇建议收藏后食用~
- 注:本期博客内容可能不会使得我们写代码的能力提高,但是,这期博客是学习计算机深层次的知识,是内功的修炼,学会这些内容,我们才能在面试笔试场上游刃有余,脱颖而出!
文章目录
- 引入
- 浮点数的存入
- 浮点数的取出
- 引入的解释
- 尾声
引入
我们来看这个代码,伙伴们可以思考一下,输出的结果是什么。
按照我们以往学习的经历和感觉,有伙伴会说,是四个9。
然而答案是:
为什么会出现0.000000和这个1091567616? 下面就跟随博主的步伐,了解并学习浮点数在内存中的存储,我们就能明白了。
浮点数的存入
n
和*pFloat
明明是同一个数,为什么浮点数和整数解读会有这么大差距,这表明,浮点数和整数放进去,拿出来的方式是不一样的。根据国际标准IEEE(电气和电子工程协会)754,任意一个二进制浮点数V可以表示成下面的形式
(-1)^ S×M×2^E
(-1)^S表示符号位,当S=0时,V为正数;当S=1时,V为负数
M表示有效数字,大于1小于2
2^E表示指数位具体S、M、E代表什么,我们来举一些例子
十进制的5.0:
写成二进制就是101.0,注意,小数点后的0代表是2^-0
所以101.0可以表示成1.01*2^2
因此我们可以得出S=0(代表是为正),M=1.01(代表有效数字),E=2(代表指数位位2)
所以5.0可以写成二进制的
(-1)^0乘1.01乘2的2次方十进制的-5.5:
写成二进制就是-101.1。注意,小数点后的1代表2的负一次方。
-101.1可以写成-1.011*2^2
所以S=1(代表是负数),M=1.011(代表有效数字),E=2(代表指数位为2)。
所以-5.5可以写成:
(-1)^1乘1.011乘2的2次方
了解完浮点数如何改写成二进制的规定形式之后,接下来,S,M,E这些数字如何放进内存里面呢?
IEEE 754规定
对于单精度浮点数(比如float
类型),也就是占4个字节的浮点数(1个字节8个比特位),也就是32为浮点数:
最高位存S,接着的8位存E,剩下的23位存M
图片来自于比特就业课:
IEEE 754规定
对于双精度浮点数(比如double
类型),也就是占8个字节的浮点数(1个字节8个比特位),也就是64为浮点数:
最高位存S,接着的11位存E,剩下的52位存M
图片来自于比特就业课:
对于有效数字M,和指数E,在存入的时候还有一些特殊的规定:
对于有效数字M:
首先M是二进制数字,而且通过移动小数点的位置,我们得到的有效数字M肯定是小于2大于1的,即1<=M<2,
因此,有效数字M可以表示成1.xxxxxxx
的形式。
即,存入的时候,小数点左边的1需要存吗,没有必要,因为是固定的1,我们不需要浪费一个比特位存这个固定的值,因此,我们只需要存后面的xxxx即可。
将第一位舍去之后,相当于在32位下我们可以保存24位有效数字
对于指数E,就相对比较复杂了: 首先,E的类型是无符号整数(
unsigned int
类型),在32位下它的范围是0 ~ 255(因为8个比特位,全1时为11111111,表示255,全0时表示0),在64位下它的范围时0 ~ 2047。
看到这里,有伙伴会问了,既然E是unsigned int
类型,但是E是有可能时负数的啊?
比如十进制0.5 它的二进制就是0.1 也就是1.0*2^-1,那正负号怎么表示呢? 因此,IEEE 754规定:
在存入E的时候,必须对E的真实值再加上一个中间数
。 在32位下,这个中间数是127,在64位下这个中间数是1023。 比如,2^10的E是10,所以保存成32位浮点数时,必须保存成10+127=137。
看到这里,可能很多伙伴都懵掉了,因此,我们来举几个例子即可:
我们可以用这个代码测试,打开内存,我们就可以看我们算的对不对了。
int main() {float f = 5.5;float f2 = 0.5;return 0;
}
对于5.5:
首先:
可以写成101.1
也就是1.011*2^2
所以,此时S=0,E=2,M=1.011
所以存进去的时候,S存0
,E存2+127=129(1000 0001
),M存011
也就是
0 10000001 011
后面还有20位怎么办:补0即可
所以结果是:0 10000001 01100000000000000000000
这串数字我们四个四个分开,改成16进制
0100 0000 1011 0000 0000 0000 0000 0000
也就是
0x40b00000
,ok得出答案,我们f10调试,打开内存
果然是,0x40b00000
,这样,我们不久搞清楚存进去的方式了吗
第二个数0.5,伙伴们可以自己动笔算一下,算出来再对一下答案哦!
浮点数的取出
浮点数在取出的时候,还要分为三种情况讨论:
- 情况1:E不为全0或不为全1时:
此时,取出的方式和存进去的相反,怎么存怎么取。 将指数E减去127(或1023),得到真实值,然后再将有效数字M前加上第一位的1。 - 情况2:E为全0:
此时,浮点数的指数E等于1-127或(1-1023)得到真实值,有效数字M不再加上第一位的1,而是还原为0.xxxxxxx
的小数。这样其实时为了表示±0这个数,因为当E的比特位上全部都是0的时候,其实原来的数字是带着2的负126次方或2的负1023次方的,是一个很小的数字,所以计算机直接将其解析为0。 - 情况3:E为全1
同理,和全零类似,全1的数字带着2的126次方的指数(或1023次方),是个很大的数字,当计算机看到全1的时候,直接解析成无穷大。
引入的解释
其实看到这里,我们对浮点数在内存中的存储已经了解地非常深入了,这些知识储备足够我们应付笔试和面试官的提问。
接下来,我们看回这题:
现在,用我我们所学的方法,解释那个答案是怎么出来的。
首先,9以整型的形式存入内存: 先翻译成原码:
00000000000000000000000000001001
~9的原码
然后因为是正的,原反补相同 所以存进内存的9的补码为:
00000000000000000000000000001001
~9在内存中的形式 接下来我们以浮点数的形式取出来
我们先划分一下这32个bit位,划分出S,E,M的位置先:
0 00000000 00000000000000000001001
~被解析成浮点数、
此时的E,我们发现是一个全0,说明这个9被看成浮点数的时候,是一个无限接近于+0的数字,而由于精度有限制,所以打印的就是0.000000
紧接着,我们看当9.0以浮点数的形式存入的时候: 转化成二进制,即
1001.0
即:(-1)^0 * 1.001 * 2^3
此时:S=0、M=1.001、 E=3 +127 =130~10000010
因此存进内存的是:
0 10000010 00100000000000000000000
当这个数被看作整数以%d的形式
打印的时候,由于符号位为0。原反补相同,因此,01000001000100000000000000000000
直接被解析成整数,换算成10进制就是1,091,567,616
,这正是我们打印出来的结果!
所以,搞懂浮点数在内存中存储之后,我们就可以很好地解释那个结果了。
尾声
虽然本期博客内容可能不会使得我们写代码的能力提高,但是,这期博客是学习计算机深层次的知识,是内功的修炼,学会这些内容,我们才能在面试笔试场上游刃有余,脱颖而出!
因此,在临走之前,不要忘了你的点赞关注和收藏哦!
【数据的存储】浮点数在内存中的存储详解【超详细的保姆级别教程,让面试官心服口服】手撕浮点数存储使用方式相关推荐
- java 内存分布_java的各类型数据在内存中分配情况详解_
1. 有这样一种说法,如今争锋于IT战场的两大势力,MS一族偏重于底层实现,Java一族偏重于系统架构.说法根据无从考证,但从两大势力各自的社区力量和图书市场已有佳作不难看出,此说法不虚,但掌握Jav ...
- 猿猴:String类在内存中实现原理详解
(1)==和equals区别 ==:在引用类型比较是,==比较地址值是否相同 equals:引用类型比较时,equals默认也是比较地址值是否相同,而String类重写了equals()方法,比较的是 ...
- 猿如意中的【ApiFox】工具的安装与使用教程,超详细,保姆级教程看这一篇文章就够了。
目录 一.什么是猿如意 二.猿如意中下载安装 ApiFox 2.1.如何下载和安装 2.2.什么是 ApiFox? 三.关于 ApiFox 的介绍以及使用 1.基本介绍 2.支持API文档导入 3.接 ...
- C/C++浮点数在内存中的存储方式《转》
那天有人在汇编群里有人问了一个 #include <iostream> #include <stdio.h> using namespace std; int main() { ...
- IEEE754标准: 浮点数在内存中的存储方式
一. 什么是IEEE754标准 我们知道, 计算机内部实际上只能存储或识别二进制. 在计算机中, 我们日常所使用的文档, 图片, 数字等, 在储存时, 实际上都要以二进制的形式存放在内存或硬盘中, 内 ...
- 【C语言进阶】③探究浮点数在内存中的存储方式
文章目录 一.例题 二.浮点数在内存中存储方式 2.1国际标准IEEE(电气和电子工程协会)754规定: 2.2实际上,浮点数在内存的存储形式为: 2.3具体M和E是怎么算的呢? 三.题解 3.1刚开 ...
- 浮点数在内存中的存储
我们已经介绍过整数在内存中的存储方式,那浮点数在内存中是怎样存储的呢? 先看一段代码: #include<stdio.h>int main() {int n = 9;float* pFlo ...
- 浮点数在内存中的存储——“C”
各位CSDN的uu们你们好呀,今天,小雅兰的内容是浮点数在内存中的存储,昨天我们已经写过了整型在内存中的存储,那么,浮点数在内存中是怎样存储的呢?现在,就让我们进入浮点数在内存中的存储的世界吧 常见的 ...
- 详解浮点数在内存中的存储
目录 前言 一. 32 位单精度浮点数在内存中的存储 1.1 - 符号位 sign 1.2 - 偏移后的指数位 biased exponent 1.3 - 尾数位 fraction(mantissa) ...
最新文章
- Partial Class部分类
- 国外开源威胁情报feed站点 简介
- slf4j介绍及配置详解
- 执行命令npm install XXX后仍然提示 Cannot find Module XXX
- OCF 试图为物联网建立标准,但它面临着不小的挑战
- java类全路径简写_[JAVA] JAVA 类路径
- 启牛商学院计算机,启牛商学院达摩老师教你三招成为跨界理财达人
- SQLite集成与用法
- 昆石VOS2009/VOS3000 2.1.6.00 新功能介绍目录
- android友盟分享最新,Android 友盟分享+第三方登录
- 【踩坑笔记】java使用poi导出word文档换行
- 闲谈mac地址学习以及IVL/SVL
- Windows 取证之$MFT
- 爬虫搜索并下载网易云歌曲
- 织梦选php哪个版本,织梦DedeCMS网站及其版本的判断
- USERS权限运行需管理员权限的软件
- python编程 “sitka_weather_07-2014” 等数据集
- GitLab+Shell用户周期性数据统计分析工具(自动生成HTML格式)
- python pexpect 打印匹配的值
- 实战Java高并发程序设计(第二版)-chp5并行模式与算法
热门文章
- 固态存储设备固件升级方案
- 详解js中的闭包(closure)以及闭包的使用
- 后渗透篇:COM Object hijacking 后门实现思路——劫持CAccPropServicesClass and MMDeviceEnumerator
- 重启服务器后,tomcat自动重启
- Python声明空变量
- BeanCopier工具类
- 实习生 笔试 Adobe China 2012 RD Intern Paper Test
- cue文件分割ape,flac,wav工具cuesplitter
- ML-AGENT模仿学习(一)
- 盘点10个程序员可以接私活的平台和一些建议