C语言——二周目——数据在内存中的存储

目录

一、整数的存储方式

二、浮点数的存储方式


一、整数的存储方式

        因为CPU只有加法器,所以对于整型来说,数据在内存中通常采用补码的方式进行储存。

        在这里复习一下原码、反码、补码。

正数和无符号数的原码、反码、补码相同;

负数的原码是把数字按二进制直接翻译,反码是原码除符号位按位取反,补码是反码+1 。

int a = 20;

// 0000 0000 0000 0000 0000 0000 0001 0100 —— 原码

// 0000 0000 0000 0000 0000 0000 0001 0100 —— 反码

// 0000 0000 0000 0000 0000 0000 0001 0100 —— 补码

// 0x00 00 00 14

int b = -10;

// 1000 0000 0000 0000 0000 0000 0000 1010 —— 原码

// 1111 1111 1111 1111 1111 1111 1111 0101 —— 反码

// 1111 1111 1111 1111 1111 1111 1111 0110 —— 补码

// 0x ff ff ff f6

        我们所熟知的int类型通常在内存中占用4个字节的空间,而short类型占用2个字节,char类型则使用1个字节的空间。所以我们敏锐的察觉到,既然空间有限,那么总会有空间存不下的数字,这时候怎么办呢?

        这便引出了溢出的问题。我们以char类型为例子,来讨论一下数字变化规律。

C语言——二周目——数据在内存中的存储_第1张图片

 我们从中可以发现一些比较实用的规律:

        ①-1的补码二进制位全为1;

        ②对于一个有符号整数家族的类型,其所能表示的最小的负数为符号位取1,其余位取0;

        ③溢出发生在所能存储的最大值变为所能存储的最小值;

二、浮点数的存储方式

任意一个二进制浮点数可以表示为该形式: (-1)^S * M * 2^E

(-1)^S 表示符号位,S=0为正数,S=1为负数;

M表示有效数字;

2^E表示指数位。

例如,5.0二进制是101.0,相当于1.01 * 2^2。得到S=0,M=1.01,E=2 。 

        以上便是二进制的科学计数法的表示,可以类比我们熟悉的十进制的科学计数法来学习。

对于32位的浮点数(float),最高的1位是符号位S紧接着8位是指数E剩下的23位是有效数字M

C语言——二周目——数据在内存中的存储_第2张图片

对于64位的浮点数(double),最高的1位是符号位S紧接着11位是指数E剩下的52位是有效数字M。其内部存储方式与float大同小异,区别在于double的偏置值位1023,即储存E时要在实际指数的基础上加1023.

小结一下:

1)M一定为1.xxxxxx,所以默认舍去1,只保留xxxxxx这一部分。如1.01只保存01;

2)E有可能为负数,所以存入E时会加上一个中间数,E为8位时中间数为127,E为11位时中间数位1023。如2^10,保存为32为浮点数时,保存为10+127=137,即1000 1001。

3)E从内存中取出分为三种情况:

        ①E不全为0或不全为1:E减去127(或1023),在M前加上第一位的1。

        ②E全为0:此时E的真实值为-127(-1023),有效数字M不再加上第一位的1,而是还原为0.xxxxxx的小数,以表示+-0或接近于0很小的数字。

        ③E全为1:此时如果有效数字M全为0,表示+-无穷大。

你可能感兴趣的:(c语言)