前言
本文将介绍数据在内存中的存储。
说明:了解数据在内存中如何存储,利于后面学习对数据的调用。
整数数据类型在内存中的存储
原码:
一组二进制数
反码:
只要硬件电路中有加法器,计算机就能做减法。
正数的反码和原码一样。(正数没有反码,或不需要反码,但为了定义上完整所以规定正数的反码和原码相同)
负数的反码,除了符号位外,是对其原码逐位取反。
注: 符号位存在于有符号数据类型中,无符号数据类型没有符号位。符号位指的是数据的最高位(也就是最左边的一位)。当符号位是1时,表示这个有符号数据类型是负数。
补码:
正数的补码和原码一样。
负数的补码是在其反码的的末位加1。
例子: 假设a,b都为正数 a - b = a + b的补码 = a + ( b的反码 + 1 )
对于补码,有一种投机取巧的方式,即补码是在原码的基础上从最右边开始算,遇到第一个1后,后面的所有数(符号位除外)都取反,如源码:10101010的补码:11010110( 右边第一个1开始除符号位外,都取反 )。
对于所有的数在计算机中,数值的存储都是以补码存储的
所以如果是八位的话能表示的最小整数为 10000000(补码) = -1*27 = -128;能表示对最大整数为 01111111(原码/补码) = 27 - 1 = 127;
注意: 这里的正数是从0到127,有128个数。负数时从-128到-1,有128个数。
-127的补码 = 10000001: 原码: 11111111
10000000(补码) - 1 = 111111111(反码) 反码取反 = 10000000(原码)
所以10000000 = -0 (-0=0),但是在计算机里面,由于是补码储存,所以规定-0就是-128。
注: 最小值-128的原码、反码、补码分别为10000000、11111111、10000000
存储数据
数据在内存中的存储方式并不是我们想象的那样,而是从右向左进行存储的。其实计算机中存储数据是有两种模式的,一种是 大端模式 ,一种是 小端模式 。
十六进制是0x12 34 56 78,则78属于低位字节,12属于高位字节。
大端模式
大端模式: Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。
(其实大端模式才是我们直观上认为的模式,和字符串存储的模式相类似)地址由小向大增加,而数据从高位往低位放
低地址 ——————> 高地址
0x12 | 0x34 | 0x56 | 0x78
小端模式
小端模式: Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。
低地址 ——————> 高地址
0x78 | 0x56 | 0x34 | 0x12
浮点数据类型在内存中的存储
根据国际标准IEEE(电气和电子工程协会) 754,任意一个二进制浮点数V可以表示成下面的形式:
(-1)^S M 2^E
(-1)^s表示符号位,当s=0,V为正数;当s=1,V为负数。
M表示有效数字,大于等于1,小于2。
2^E表示指数位。
以9.0为例,首先我们写出9的二进制是1001,然后再写出小数点右边的二进制,所以最后是1001.0,小数点后的二进制刚开始权重是 2−1 , 然后 2−2 这样,例如 5.5 就是 5 的二进制是 101 ,然后小数点后是 1 ,因为 12−1 = 0.5 。回到 1001.0 ,把 1001.0 写成科学计算法的形式,就是 1.0012^3 ,最后化成标准就是 (-1)^01.0012^3 ,此时 S = 0,M = 1.001,E = 3。
那S,M,E在内存中是怎么存储的?
IEEE 754规定:
对于32位的浮点数,最高的1位是符号位s,接着的8位是指数E,剩下的23位为有效数字M。
对于64位的浮点数,最高的1位是符号位S,接着的11位是指数E,剩下的52位为有效数字M。
IEEE 754对M和E有特别的规定,这里就暂时不说了,感兴趣可以自己去查下。