目录
浮点数篇
![](https://img-blog.csdnimg.cn/20210817180554538.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81ODg0MzcxNw==,size_16,color_FFFFFF,t_70)
前后声明的值都为9,但是在整形类型输出和浮点数类型输出时产生明显的差异,就说明整数类型和浮点数类型在内存当中存储的形式是完全不同的。那么浮点数类型在数组当中是怎样存储和取出的呢?
(一)浮点数类型在内存当中的存储
(-1)^s表示**符号位**,当s=0,V为正数;当s=1,V为负数。
M表示**有效数字**,大于等于1,小于2。
2^E表示**指数位**。
例1: (十进制 )5.5->101.1(二进制),即(-1)^0 * 1.011 * 2^2。此时,S=0; M=1.011; E=2;
安排如下图:
![](https://img-blog.csdnimg.cn/20210817182225823.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81ODg0MzcxNw==,size_16,color_FFFFFF,t_70)
规则:
1.S是0就放0,是1就放1;
2.由于E可能出现负数,即0.5就是2的负一次方,E=-1。这是由于八位存储可以最大范围(不同平台范围会有差异)是0~255,规定存储时将原来的E0+127(范围的中间值)=E(新E),转换为二进制位后存储到八位当中。比如,2^10的E 是10,所以保存成32位浮点数时,必须保存成10+127=137,即10001001。
3.M因为是大于等于1,小于2,所以存储时去掉1,只保存小数点后面的数。这样可以保存到小数点后24位,相比于保存1,只保存到小数点后23位来说更加精确。并且如果不到23位后面自动补0。
这里我们根据上述分析一个存储的例子:
(二)浮点数取出(因E而不同)
1.E这8位不全位0或者不全为1。这时浮点数正常E-127=E0,得到真实值,再将有效数字M前面加上1。例如0.5:
2.E全为0。这时浮点数E直接等于1-127=-126;M不加1,直接取0.xxxxxx,这样的小数,这样做的目的是表示+-0,十分接近0 的一个数字。原因:E=0,即E0+127=0->E0=-127.2^(-127)这个数字太小了,所以出此上策。
3.E全为1。二进制位表示255,255-127=128,2^128,这个数字非常大。所以直接表示+-无穷大。
这样就可以解释之前的那个例子了。相关注释在代码中:
#include <stdio.h>
int main()
{
int n = 9;
//正数原码反码补码相同
//二进制序列为:
//00000000 00000000 00000000 00001001
//转换为float类型放到内存当中存储默认为:
//S:0;E:00000000;M:00000000000000000001001
//向外取得时候认为E为全0,则E=1-127=-126,M=0.00000000000000000001001
//%f打印的数字就是:(-1)^0 * 0.00000000000000000001001 * 2^-126无限接近0
float* pFloat = (float*)&n;
printf("n的值为:%d\n", n);
printf("*pFloat的值为:%f\n", *pFloat);//以%f打印时默认只能打印到小数点后6位,所以显示0.000000
*pFloat = 9.0;
//二进制形式:1001.0
//(-1)^0 * 1.001 * 2^3
//S=0;M=1.001;E=3
//存储时:0 3+127=130 001(不够23位自动在后面补0)
//即为:0 10000010 00100000000000000000000
printf("num的值为:%d\n", n);
//以%d形式打印时,默认将他看为有符号数,二进制换算为十进制为1091567616
printf("*pFloat的值为:%f\n", *pFloat);
//float 形式向外取时,E不是全0也不是全1,正常拿取。
//或者另一种理解,以浮点数形式存储一浮点数形式输出二者的值应该是一样的。
return 0;
}
大小端的介绍即判断
(一)介绍:
1. 小端字节序存储:把一个数据的低位放在低地址处,高位放到高地址处。
2.大端字节序存储:把一个数的低位字节内容放在高地址处,高位字节内容放在低地址处。
##为什么会存在大小端之分?
每个地址都对应着一个字节,当存储数据将多个字节安排超过一个字节时,就会存在存储顺序的问题。
(二)大小端的判断
整形在内存中的存储
首先,整形在内存当中的存储是以补码的形式进行存储的。这就涉及到两个问题:
(1)原码反码补码的概念:
原码:直接将二进制按照正负数的形式翻译成二进制
反码:原码符号位不变,其他位按位取反
补码:反码加一得到补码
注:1.正整数的原码反码补码相同。
2.符号位不变,原码按位取反再加1得到补码,同样补码按位取反再加一得到原码。
(2)为什么要用反码存储,不用原码?
因为,使用补码,可以将符号位和数值域统一处理。CPU当中只有加法,在运算当中,补码优于原码。举个例子:
如有错误,欢迎指正!让我们一起加油吧!