【C语言】深度剖析整型和浮点型在内存中的存储


目录

一、整型在内存中的存储

1、原码、反码、补码

1.1原码、反码、补码存在的意义

1.2样例

1.3大小端存储模式

二、浮点型在内存中的存储

1、浮点型的存储规则

2、浮点型的存储

3、浮点型的取出

3.1 E中有0有1

3.2 E为全0(很小的数)

3.3 E为全1(很大的数)


d3cd588c7061712d572c06f240ff2ccc.gif一、整型在内存中的存储

e86de582b9cc622fa7b21c3aca08266c.gif1、原码、反码、补码

1、若整型的数据类型为signed类型,则数据的二进制最高位为符号位;若整型的数据类型为unsigned类型,则数据的二进制没有符号位,所有的二进制位均能存储数据。

2、正数原码、反码、补码相同。

3、负数的原码、反码、补码关如下:

原码:直接将原始数据按二进制的形式进行转换得到的就是原码。

反码:将原码的符号位不变,其他位按位取反,若无符号位,全部取反即可。

补码:反码+1。

注:补码可以通过同样的方式,正推或者逆推得到原码。

1.1原码、反码、补码存在的意义

1、在计算机系统中,数值一律用补码来表示和存储。加法和减法可以统一处理(CPU只有加法器)此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。

2、对于+0(0000)和-0(1000)时,若采用原码存储,0将会有两个不同的二进制表示形式,产生混乱。采用原、反、补码将能解决该问题。

1.2样例

int main()
{
    char a[1000];
    int i;
    for(i=0; i<1000; i++)
   {
        a[i] = -1-i;
   }
    printf("%d",strlen(a));//打印255
    return 0;
}

打印结果255。

分析:signed char的取值范围为-128~127,该题内的数组元素为[-1,-2,······,-128,127,126,······,1,0,-1,······],由于strlen遇到'\0'即停止,所以本题输出255。图解如下所示:

1.3大小端存储模式

1、小端存储:将数据的低位保存至内存的低地址处,将数据的高位保存至内存的高地址处。

2、大端存储:将数据的低位保存至内存的高地址处,将数据的高位保存至内存的低地址处。

大小端的存储方式是由CPU来决定的,我们常用的 X86 结构是小端模式,而 KEIL C51 则为大端模式。很多的ARM,DSP都为小端模式。有些ARM处理器还可以由硬件来选择是大端模式还是小端模式。

百度2015年系统工程师笔试题

请简述大端字节序和小端字节序的概念,设计一个小程序来判断当前机器的字节序。

#include <stdio.h>
int main()
{
	int i = 1;//1在内存中的二进制码为0X00 00 00 01
	if (*(char*)&i == 1)
	{
		printf("小端");
	}
	else
		printf("大端");
	return 0;
}

48ae77acb8e9c737439cff5bc180c926.gif二、浮点型在内存中的存储

516c0ac57ab354ad7363317206d9e6eb.gif1、浮点型的存储规则

根据国际标准IEEE(电气和电子工程协会)754,任意一个二进制的浮点数V可以表示成下面的形式:

(-1)^S*M*2^E
(-1)^S表示符号位,当S=0时,V为正数;S=1时,V为负数
M表示有效数字,M大于等于1,小于等于2
2^E表示指数位


4fe38cf3968a580b5bf1f0e614af000b.gif2、浮点型的存储

举例:十进制浮点数的5.0,写成二进制是101.0,相当于1.01×2^2。

那么这里的S=0;M=1.1;E=2。

IEEE754对于有效数字M和指数E还有一些特别的规定:

有效数字M:前面说过,1≤M<2,所以M可以写成1.xxxxxxx,xxxxxxx表示小数部分。因为第一位恒为1,所以该标准规定保存有效数字时舍去1,只保存小数部分,这样可以用有限的二进制位多保存一位有效数字。例如M=1.01,在保存是将会舍弃第一位的1,只在内存中保存01。

指数E:E是一个无符号整数,如果E为8位,那么E的取值范围为0~255,如果E为11位,那么E的取值范围为0~2047。

但是E是可以存在负数的,所以存入内存中的E必须加上一个中间数,8位+127,11位+1023。比如5的E是2,以8位为例,那么存入内存中的E是2+127=129。即10000001。

若以整型指针取出这个数,将会是一个非常大的值。

49de7641d75aab50fca2c8e203ca3b86.gif3、浮点型的取出

3.1 E中有0有1

指数E的值减去127(或1023),得到真实值。

将有效数字M前加上第一位的1。

3.2 E为全0(很小的数)

指数E的值为(1-127)或(1-1023)即为真实值。

有效数字不再加上原来的1,而是还原为原来的小数0.xxxxxxx,这样做是为了表示±0,以及接近于0的很小的数。

3.3 E为全1(很大的数)

E全为1,以8位为例,说明该数的二进制指数移动了128位,这将是一个非常大的数。

猜你喜欢

转载自blog.csdn.net/gfdxx/article/details/125002817