整数和浮点数在内存中的存储

本文详细探讨了整数和浮点数在内存中的存储原理,包括大小端字节序的区别,整数的原码、反码和补码表示,以及浮点数的二进制转换和IEEE754存储模型。特别关注了单精度和双精度浮点数的存储结构,通过实例帮助读者理解浮点数如何表示为科学计数法形式并存储在内存中。
摘要由CSDN通过智能技术生成

@TOC整数和浮点数在内存中的存储

一级目录一:大小端字节序

1:什么是大小端
2:如何判断大小端

二级目录

二:整数在内存中的存储
1:原码,反码,补码

三级目录

三:浮点数在内存中的存储
1:浮点数的二进制转换
2:浮点数在内存中的存储
2.1浮点数存的过程
2.2浮点数取的过程

总结

一大小端字节序
1.什么是大小端
对于一个整数,我们假设它为1,取它的一个字节,当数据只在一个字节内存存储时,我们书写习惯一般是从高位到低位,如这里的1,就是0001,但是当数据超过一个字节后。这就涉及到了数据在内存中存储时大端还是小端的问题了。如果低地址存放高位数据,高地址存放低位数据,就是大端字节序;如果低地址存放低位数据,高地址存放高位数据,就是小端字节序。比如一个16进制的整数8,他的值为0x1000,如果是大端存储就是0x0001,小端存储就是0x1000。这就是大端小端的由来,就是根据数据的高位是存在于高地址还是低地址。
2:如何判断大小端
那么我们如何判断该整数是大端存储还是小端存储了,这里以一个代码为列子进行解释。
在这里插入图片描述
二:整数在内存中的存储
首先整数都是以二进制在内存中存储
1原码,反码,补码
计算机中整数的二进制表示形式有三种:原码、反码、补码。其中补码是数据存放在内存中的形式。
原码、反码、补码的三种表是形式均存在符号位和数值位两部分。
正数:
正数的原码、反码、补码都相同。即将一个正整数换算为二进制形式,即得到其原码、反码、补码。
int a = 10;
00000000 00000000 00000000 00001010 ——原码
00000000 00000000 00000000 00001010 ——反码
00000000 00000000 00000000 00001010 ——补码

负数:
负数的原码、反码、补码各不相同。
原码
直接将负数按照正负数的形式翻译为二进制,就可以得到原码
负数的符号位应为1
反码
将得到的原码符号位不改变,其余位按位取反,得到反码
即:将原码的符号位不改变,除去符号位,其余所有位都改为相反值(0改1,1改0)
补码
将得到的反码加1,即可得到补码
int a = -10;
10000000 00000000 00000000 00001010 ——原码
11111111 11111111 11111111 11110101 ——反码
11111111 11111111 11111111 11111110 ——补码

在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值位统一处理。同时,因为CPU只有加法器,所以加法和减法也可以统一处理。
补码转换为原码,与,原码转换为补码的方式是想通的,不需要额外的硬件电路。
这里以10-5做列子讲解:
我们可以把10-5这一减法转换为10+(-5),然后再通过加法器进行计算
int a = 10;
int b = -5;
int c = a + b;
10:
原码/反码/补码:00000000 00000000 00000000 00001010
-5:
原码:10000000 00000000 00000000 00000101
反码:11111111 11111111 11111111 11111010
补码:11111111 11111111 11111111 11111011
10+(-5):
10的补码: 00000000 00000000 00000000 00001010 0x0000000a
-5的补码: 11111111 11111111 11111111 11111011 0xfffffffb
1 00000000 00000000 00000000 00000101
因为整型只能存放4个字节的内容,所以发生截断最后结果为:
00000000 00000000 00000000 00000101
三:浮点数在内存中的存储
首先介绍一下啥是科学计数法
科学记数法是一种记数的方法。把一个数表示成a与10的n次幂相乘的形式。
科学记数法的形式是由两个数的乘积组成的。表示为a10^b或者`aEb。其中a的取值范围1≤|a|<10。
如0.00001=1
10^-5=1E-5
1:浮点数的二进制转换
如将4.75转换为二进制形式

  1. 先将整数 4 转换为二进制形式
    00000100
    2.再将小数部分 0.75 转换为二进制形式 ,B代表二进制的符号 ,D代表10进制的符号
    对于二进制小数部分,0.1(B) == 2^-1 = 0.5(D)
    0.01(B) == 2^-2 = 0.25(D)
    故小数部分0.75的二进制形式为:0.11
    4.75的二进制形式为:0100.11
    2:浮点数的存储规则
    表示形式(-1)^S * M * 2^E
    根据国际标准IEEE(电气和电子工程协会)754,任意一个二进制浮点数V可以表示成下面的形式:
    这里还是以4.75为列子进行解释
    转换为二进制形式为:100.11。写成二进制的科学记数法形式为:1.0011 * 2^2

按照公式 (-1)^S * M * 2^E进行拆分

1.0011为正数,所以S==0,即:(-1)^0

M表示有效数字,即:M==1.0011

E为指数位,即:E=2

综合上述得:(-1)^0 * 1.0011 * 2^2
这里对32位的浮点数64位的浮点数,IEEE754有不同的存储模型
2位浮点数(单精度浮点数)存储模型:
在这里插入图片描述
最高的1位是符号位S,之后的8位是指数E,剩下的23位为有效数字M。

64位浮点数(双精度浮点数)存储模型:
在这里插入图片描述
最高的1位是符号位S,之后的11位是指数E,剩下的52位为有效数字M。
这里详细讲一下 E 和M,因为S这一位只代表符号。正数时,S为0,负数时为1
有效数字M
在将一个二进制数字V,写成IEEE754规定的形式(-1)^S * M * 2^E 时,对于有效数字M而言,1≤M≤2,M需要写成1.xxxxxx的形式,其中的xxxxxx表示小数部分。

对此,IEEE754规定,在计算机内部保存M时,默认这个数字的第一位总是1,因此可以被舍去,只保存后面的xxxxxx部分。比如在保存1.01时,只保存01,等到读取的时候,再把小数点前面的1加上。这样做的目的是为了节省1位有效数字。

以32位浮点数存储模型为例,留给有效数字M的空间为23位。如果第一位的1不再保存,等于可以保存24位有效数字。(23位小数点后数字+1位默认存在舍去的1)
指数E
E为一个无符号的整数(unsigned int),这说明,如果E为8位,它的取值范围为0255;如果E为11位,它的取值范围为02047。但是,科学记数法是可以出现负数的。

所以IEEE754规定:存入内存时,E的真实值必须再加上一个中间数,对于8位的E,这个中间数是127;对于11位的E这个中间数是1023。

例如:2^2的E是2,在保存成32位浮点数时,必须保存成2+127=129,即:1000 0001;然后存入到模型中E的位置。
对于E,这里有三种特殊的情况
E不为全0或者E不为全1

当E不为全0或者E不为全1的情况时,浮点数采用下面的规则表示:指数E的计算值减去127(1023),得到真实值,再将有效数字M前加上第一位的1。

E为全0

当E为全0时,浮点数的指数E等1-127(或者1-1023)即为真实值,此时有效数字M不在加上第一位的1,而是还原成0.xxxxxx的小数形式。这样做是为了表示±0,以及接近于0的很小的数字。

E为全1

这时,如果有效数字M全为0,表示±无穷大(政府取决于符号位S)。
这里有一个很经典的代码,我们以他为列子讲述一下整数和浮点数在内存中的存储
在这里插入图片描述
这里我一一解释一下出现这些值的原因
先解释一下前面一部分
9的补码为:00000000 00000000 00000000 00001001 == 0x 00 00 00 09
int n在内存中开辟一块4个字节大小的内存空间
&n取出n所指向的内存地址,强制类型转换为(float* ),将这块内存空间的地址赋值给了,指针类型为float*的pFloat。
以%d的形式打印n时,其值并未遭到改变,以整型的形式存入,再以整型的形式取出打印,所以输出为9
以%f的形式打印时,以整型的形式存入,以浮点数的形式取出
内存中补码为:00000000 00000000 00000000 00001001 将其按照补码的形式进行取的时候,即按照32位浮点数模型进行拆分
得到:S=0
E=00000000
M=0000000 00000000 00001001

上文说到,当指数E全为0时,指数E等于1-127(1-1023)即为真实值。有效数字M不再加上第一位的1,而是还原成0.xxxxxx的小数。

此时指数E全为0,则浮点数V写成:

V=(-1)^0 * 0.00000000000000000001001 * 2^(1-127) = 1.001 * 2^(-126)

此时V是一个很小的无限接近于0的正数,所以用十进制小数表示为0.000000
这里解释一下后面的一部分
pFloat = 9.0;将9.0以浮点数的形式存入到 *pFloat所指向的内存空间

9.0转换为1001.0,科学记数法为 1.001*23,转换为**(-1)S * M * 2^E**的形式得到

(-1)^0 * 1.001 * 2^3 得到 S=0,E=3+127=130,M=1.001

E=130 转换为二进制为10000010

M去除1存储为001,后面补齐20个0

最终浮点数9.0在内存中存储为:0 10000010 00100000000000000000000

以浮点数的形式存储,以整型的形式往外取,则直接将01000001000100000000000000000000看成一个整型的存储方式,换算为十进制为1091567616

以浮点数的形式存储,以浮点数的形式往外取,则为9.000000。
总结::
这里就是整数和浮点数在内存中存储的全部内容了。重点介绍了浮点数在内存中的存储,希望大家通过这篇博客能够了解这一部分的知识。本人水平有限,有些地方没讲到还请大家谅解,同时如果大家找到错误的话,麻烦告知一下。十分感谢!!
时人不识凌云木,直待凌云始道高。慢慢积蓄,最终会登上山顶。大家加油,我们下篇博客见了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值