C++中各类数据的存储方式
准备知识:
- 计算机中存储的数据类型采用的是补码
- 正数的补码与原码相同,负数的补码 = 反码 + 1
- 反码:符号位不动,各位上的值按位取反
- 符号位:1表示负数,0表示整数
(一)以windows32位系统为例子,各类型数据占用的内存大小:
(二)类型储存
1:bool
bool 返回的是代表真假的true、false值,在内存中用一个字节(8个位)来表示,没有什么特殊之处;
2:char
char 是字符型,在内存中占用一个字节(8个位),每个位置可以是0,也可以是1。如下图所示:
每个位置都存在0或1两种状态,一共8个位置,就会存在2^8=256个状态,所以char行就可以表示256个不同的值,只是当有符号和无符号时,表示的范围不相同。
字符型在内存中都是存储相对应的ASKLL码值,比如字符‘A’,它的ASKLL码值为65,那么在内存中的8个位应该表示为如下图所示:
3:short、int、long
这三种类型表示整数,每种类型在内存中的长度分别为2、4、4字节,即16位、32位、32位。当然有符号和无符号所表示的数字范围也是不相同的。
4:float、double
float类型的数据在内存中占四个字节(32bit),(从右往左数)即低地址到高位地址依次叫第0位和第31位,着32位可以分为3个部分:符号位(低31位)、阶码(功8位,从30位到23位)、尾数(剩下的低位23个位)。
其中:符号位 -> 0表示整数,1表示负数
阶码 -> 表示该实数转换为规格化的二进制实数后的指数与127(127在这里为偏移量)之和,规格化的二进制实数只能在 -127~ +127 之间。
尾数 -> 表示该实数转换为规格化的二进制实数后小数点以后的剩余位。
double类型与float类型的存储方式相同,只是各部分占用的位数不相同,如下图所示:
例一:将十进制178.125表示成机器内的32个字节的二进制形式.
1:将128.125表示成二进制数:
(178.125)(十进制数)=(10110010.001)(二进制形式);
:2:将二进制形式的浮点实数转化为规格化的形式:
10110010.001=1.0110010001*2^7 (小数点向左移动7个二进制位可以得到)
:3:符号位:
该数为正数,故第31位为0,占一个二进制位.
4:阶码:
指数为7,故其阶码为127+7=134=(10000110)(二进制),占从第30到第23共8个二进制位.
:5:尾数:
为小数点后的部分, 即0110010001.因为尾数共23个二进制位,在后面补13个0,即01100100010000000000000
:6:178.125在内存中的实际表示方式为:
0 10000110 01100100010000000000000
例二:将-0.15625表示成机器内的32个字节的形式.
1:将-0.15625表示成二进制形式:
(-0.15625)(十进制数)=(-0.00101)(二进制形式);
2:将二进制形式的浮点数转化为规格化的形式:
(小数点向右移动3个二进制位可以得到) -0.00101=-1.01*2^(-3)
3:符号位:
该数为负数,故第31位为1,占一个二进制位;
4:阶码:
指数为-3,故其阶码为127+(-3)=124=01111100,占从第30到第23共8个二进制位;
5:尾数:
小数点后的01,当然后面要补21个0;
6:0.15625在内存中的实际表示形式为:
1 01111100 01000000000000000000000
注1:二进制小数转换为十进制小数
比如把二进制小数110.11转化为十进制小数,步骤如下:
注2:十进制小数转换为二进制小数
方法是这样的:先分别把十进制小数的整数部分和小数部分转化为二进制,然后合并即可。当然整数部分很简单,直接进行二进制转化,而小数部分就不一样了。
具体做法是:用2乘十进制小数,可以得到积,将积的整数部分取出,再用2乘余下的小数部分,又得到一个积,再将积的整数部分取出,如此进行,直到积中的整数部分为零,或者整数部分为1,此时0或1为二进制的最后一位,或者达到所要求的精度为止。比如:
所以最终得到:
参考资料:https://blog.****.net/ACdreamers/article/details/19012279
https://blog.****.net/jingr1/article/details/82758226
https://www.xuebuyuan.com/3180554.html