C++基本数据类型分析

整数类型

在32位计算机中,数据都是以DWORD(双字)的形式存储的。对于不同的整数类型有不同的存储机制,例如无符号整数的可表示的数值大小要比有符号整数大一倍,有符号整数中负数和正数的表示是不一样的。
不管是有符号还是无符号,在计算机内存中存储的时候都是“小端序”形式存放的,即高字节放在高地址,低字节放在低地址,注意是以字节为单位,而不是以1个位。


有符号整数

有符号整数在C++中用int关键字表示,占4字节,有符号整数最高位用来表示符号,被称为符号位,最高位为0表示正数,反之表示负数。故被用来表示数值的只有31位,其表示的数值范围为:0x80000000 ~ 0x7FFFFFFF,对应十进制表示为:-2147483648 ~ 2147483647。
最高位是符号位,0x80000000对应的二进制为1000 0000 0000 0000 0000 0000 0000 0000,这不是-0吗? 负数的存储是采取补码的形式,补码是原码的绝对值按位取反再加1,用来表示负数。不考虑0x80000000,最小的负数应该是0x80000001,对应原码应该是0x7FFFFFFF,所以0x80000001表示-2147483647.

无符号整数

无符号整数在C++中用unsigned int关键字表示,占4字节,32位上的每一位都表示数值,可表示数值范围为:0x00000000~ 0xFFFFFFFF,十进制表示为:0 ~ 4294967295。当无符号整型不足32位时,用0来填充剩余高位,直到占满4字节内存空间为止。得到的二进制数就是它的真正的值。


浮点数型

浮点数类型的存储方式分为两种:

  1. 定点实数存储方式
    小数点的位置固定。如果用4字节存储实数,2字节用来存储整数部分,2字节用来存储小数部分。运算效率高,但是不灵活,超过2字节就无法存储了。
  2. 浮点实数存储方式
    小数点的位置不固定。利用几个二进制位表示小数点位置,称为“指数域”,剩下的表示“数据域”和“符号域”。在计算的时候,先取出指数域,然后分割数据域得到真值,例如:655.35,指数域存储10的-2次方,数据域存储65535,运算的时候拿出来算一下就得到了真值。这种方式的优缺点和定点恰相反,效率低但是灵活。

对于现代计算机,CPU的不断升级革新,浮点实数存储方式已经普及,只有一些嵌入式设备上还能看到定点存储。

#include <cstdio>
#include <iostream>
int main()
{
	int num = 8;
	float *pNum = (float*)&num;
	printf("num的值为:%d\n", num);
	printf("*pNum的值为:%f\n", *pNum);
	*pNum = 7.2;
	printf("num的值为:%d\n", num);
	printf("*pNum的值为:%f\n", *pNum);
	system("pause");
	return 0;
}

结果如下

num的值为:8
*pNum的值为:0.000000
num的值为:1088841318
*pNum的值为:7.200000

很奇怪吧,这个结果是怎么回事呢,为什么浮点数金额整数结果差别那么大?我们来看看浮点数在计算机内部的表示方法。


浮点数编码方式
float类型的IEEE编码
float类型在内存中占4字节(32位)。最高1位用于表示符号,8位用于表示指数,其余用于表示尾数(有效数位),如图所示。
在这里插入图片描述
单精度浮点数转换为IEEE规定的标准编码,需要借助科学计数法。例如将12.25f保存到内存中,需要先转换成对应的二进制数 1100.01,利用科学计数法表示就是 1.10001 << 3,即小数点右移3位到最高为1的位,所以指数为3,符号为0(正),数值110001,总结出公式如下:

V = (-1) * S * (M<<E)

其中 V 是浮点数,S是符号数(0或1),M为尾数(有效数位),E为指数位。

科学计数法中的E是可以为负数的,所以E不能直接存入计算机中。E用8位二进制数表示,可表示范围为0~255,为了能够满足负数的情况,IEEE 754规定,要把中间数 127 当零点,即0 ~ 126表示负数,127 ~ 255表示非负数。

12.25f的指数位为 3,存入计算机时要以127为零点向右偏移3,即127+3=130,转换为二进制为 1000 0010。当取出指数时再反向运算得到3即可。浮点数的有效数位M的整数部分永远都是1,所以只保留小数部分以节省1位有效数字。在32位浮点数中,23位表示M,将第一位1省略之后,等于可以保存24位有效数字。(二进制用科学计数法,总能得到整数位是1,所以实际上可以看做是24位,默认的第一位我们可以不必表示,但是我们应该理解这一点。)

可以得到12.25f的二进制存储为:
0 10000010 10001000000000000000000

符号位:0
指数位:10000010
尾数位:1000 1000 0000 0000 0000 000

  1. E不全为0或不全为1。这是正常表示数,浮点数就采用上面的规则表示,即指数E的计算值减去127(范围:-126 ~ 127),得到真实值,再将有效数字M前加上第一位的1,但这种情况M的值肯定是在1~2之间的小数,想要取到0就要看第2种情况。

  2. E全为0。这是非正常表示数,M的值为0~1之间的小数,真正指数E的取值为1-127=-126,多这么一个1是为了补偿尾数中去掉的1,尾数为0.xxxxxx的小数。这种情况是为了表示±0.0,以及接近于0.0的很小的数字。

  3. E全为1。这是特殊值,如果尾数M全为0,表示±无穷大(正负取决于符号位s);如果尾数M不全为0,表示这个数不是一个数(NaN)。

在这里插入图片描述
有时间我会继续跟进,也可以参考下面这个地址
点击参考地址

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值