目录
1.整数表示
1.1C语言整数数据类型
1.2无符号数的编码
1.3补码编码
为什么上面C语言数据类型负数的范围要比正数的范围大1?
结论
1.4有符号数与无符号数之间的转换
原理
1.5扩展一个数字的位表示
零扩展
符号位扩展
1.6截断数字
可以看出:
①、用数据类型表示大小的数是非负数(声明为 unsigned),或者负数(默认)。
②、数据类型分配的字节数会根据机器的字长和编译器有所不同,不同的大小所表示的范围是不同的。上图唯一一个与机器有关的取值范围是 long 类型的,64位机器使用8个字节(264),而32位机器使用4个字节(232)。
③、负数的范围要比正数的范围大1。(首位表示符号位,下面解释)
就是二进制与十进制转换,最大值全1时,最小值全0时,原文罗里吧嗦的,还没下面图讲的清楚
最小值,所有位为 0 , UMinw = 0
最大值,所有位都为 1, UMaxw = 1 * (1-2^w) / 1 - 2 = 2^w - 1
结论:无符号的二进制,对于任意一个w位的二进制序列,都存在唯一一个整数介于0 到 2w-1之间,与这个二进制序列对应。反过来,在0 到 2w-1之间的每一个整数,存在唯一的二进制序列与其对应。
二进制与十进制转换,最高位前面加个-号
w位二进制数,最高位为1,其余为0,最小值TMinw = -2^(w-1 )
最高位为 0,其余为 1最大值:TMaxw = 1 * (1 - 2^(w-1)) / 1 - 2 = 2^(w-1)-1
对于任意一个w位的二进制序列,都存在唯一一个介于-2^(w-1) 到 2^(w-1)-1的整数,与这个二进制序列对应。反过来,对于任意介于-2^(w-1) 到 2^(w-1)-1的整数,存在唯一的长度为w二进制序列与其对应。(有限区间,尽可能对称,涉及c语言数据类型最小取值范围)
其实相当简单别看那些没用的公式
补码编码(有符号数)范围:黄+绿
无符号数编码范围:绿+蓝
两者公共部分相同,无需转化。
当补码在黄色区域想跳到蓝色区域直接 + 2^w
当无符号数在蓝色区域想跳到黄色区域直接 -2^w
补码编码与无符号数编码的区别就在最高位w上,补码是-2^(w-1),无符号数是+2^(w-1),所以俩者互换要+-2^w
运算可能在不同字长的整数间转换。值不变
将一个无符号数转换为一个更大的数据类型,我们只需要简单的在二进制序列前面添加 0 即可。
ps:3二进制11,扩展一位 011
将一个补码数字转换为一个更大的数据类型,我们需要在开头添加符号位。
原理:(正数的原理零扩展不考虑)其实在开头添加符号位影响到了俩位,刚添加的位w+1,与添加前的最高位w,
添加前:最高位w,值即-2^(w-1)
添加后:最高位w+1与添加前最高位的和,-2^w + 2^(w-1) = -2^(w-1)
所以值不变
ps:-3二进制101,扩展一位 1101
【101】= - 1 * 2 ^ 2 + 0 * 2 + 1 * 2 ^ 0 = -3
【1101】=- 1 * 2 ^ 3 + 1 * 2 ^ 2 + 0 * 2 + 1 * 2 ^ 0 = -3
这和上面的扩展刚好相反。即我们不需要额外的扩展一个数的位,而是减少一个数字的位数。
截断一个数字可能会改变一个它的值,这是溢出的一种形式
无符号数:从最高位开始扔
ps:原值5 =【101】,截断一位【01】,值为1
补码:从最高位开始扔,新的最高位为符号位
ps:原值-5 =【1011】,截断一位【011】,值为3
int x = 53191;//二进制【(省略16个0,1100111111000111)】
short sx = (short)x;//-12345 二进制【1100111111000111】最高位为符号位
int y = sx;//-12345
我们将 x 强转为 short,在 64位机器上,就是将 32 位的 int 截断为 16 位的short int,这个16位的位模式就是 -12345 的补码表示。当我们把它强转为 int 时,符号位扩展把高 16 位设置为 1,从而生成 -12345 的32 位补码表示。