本文介绍数据主要指整型数据与浮点数数据在内存中如何存储。
1. 数据类型介绍
1.1 整型家族
char(1字节)
unsigned char 无符号字符型,取值范围0到255
signed char 字符型,等价char,取值范围-128到127
字符存储时,存储的是对应的ASCII码值,算作整型,所以归类到整型家族中
short(2字节)
unsigned short [int] 无符号短整型,取值范围0到65535
signed short [int] 短整型,取值范围-32768到32767
int(4字节)
unsigned int 无符号整型,取值范围0到4 294 967 295
signed int 整型,取值范围-2147483648到2147483647
long(4/8字节)
unsigned long [int] 无符号长整型,取值范围0到4 294 967 295
signed long [int] 长整型,取值范围-2147483648到2147483647
32位编译环境下占用4字节,64位编译环境下占用8字节
long long(8字节)
unsigned long long [int] 无符号更长的整型,
取值范围-9223372036854775808到9223372036854775807
signed long long [int] 更长的整型,
取值范围0到18446744073709551615
1.2 浮点数家族
float(4字节)
根据IEEE754浮点数,取值范围-3.4E38到+3.4E38
double(8字节)
取值范围-1.797E308到+1.797E308
2. 整型在内存中的存储
2.1 原码,反码,补码
要理解整型如何存储,必须先知道一个数的原码,反码,补码如何得到,才能进行下一步,了解一个数在内存中存储的方式。整数数据存储在内存中的都是补码,正整数的原反补码都是相同的,负整数要通过计算得到补码。
原码
把一个十进制整数转换为二进制就得到了该整数的原码。
例如:10的原码就是00000000 00000000 00000000 00001010
反码
负数的反码是除去最高位的数字不变,其他位按位取反。
例如:-1原码:10000000 00000000 00000000 00000001
反码:11111111 11111111 11111111 11111110
补码
在反码的基础上加1就是补码
-1反码:11111111 11111111 11111111 11111110
补码:11111111 11111111 11111111 11111111
int main()
{
int a=1;
int b=-1;
return 0;
}
以上代码通过调试取出a在内存中的存储
取出b在内存中的存储
二进制11111111 11111111 11111111 11111111转化为十六进制为ff ff ff ff
电脑存储用的是十六进制,将其转换可以得到-1的补码。
3. 浮点数在内存中的存储
3.1 浮点数存储规则
根据国际标准IEEE(电气电子工程师协会)754,任意一个二进制浮点数V可以表示成下面形式:
- (-1)^S * M * 2^E
- (-1)^S表示符号位,当S=0,V为正数,当S=1,V为负数
- M表示有效数字,大于等于1,小于2
- 2^E表示指数位数
举个例子:
十进制5.5转化为二进制101.1,相当于1.011 * 2^2
按照标准,可以得到S=0,M=1.011,E=2。
十进制-5.5转化-1.011 * 2^2
相当于S=1,M=1.011,E=2.
IEEE754对于有效数字M和指数E,有一些特别的规则
有效数字M
IEEE754规定,存储时都是以1.xxxxx的形式存储,第一位默认都是1,因此可以把1省去,直接存储后面xxxxx部分,等到读取时再把1添上。这样做可以节省1位有效数字,32位浮点数中,M有效数字只有23位,省去1后,就可以保存24位有效数字。
指数E
指数E是一个无符号整数
这代表E为8位,取值范围在0到255,E位11位,取值范围在0到2047。但是科学计数法中E可以为一个负数,例如0.5存储时为(-1)^0 * 1.0 * 2^(-1),这时的E就是一个负数。因此IEEE754规定存入E的真实值时要加上一个中间数;E是8位数,这时中间数就是127,E是11位数,这时中间数是1023。例如前面E=-1,存入内存时要保存成-1+127=126,即1111 1110。