https://zhuanlan.zhihu.com/p/42704218
1.4.2【有符号数和无符号数】
数学中的数据分为正数和负数,在计算机中我们分为无符号数和有符号数,无符号数表示全是正数,有符号数表示有正数和负数。这里好比将容器贴个标签,将它贴上“无符号数”的标签,那么它里面都是正数。如果它的标签是“有符号数”,那么它里面的数据可能是正数也是负数。它里面的电路数量是一定的,它能表示的开关组合也是一定的,那么它到底是按无符号数看还是有符号数看,关键在于它标签是什么。
例1:数据宽度为4位的容器能存储的数据转换为十六进制为“0~F”,那么它们是如何表示为有符号数、无符号数的呢?
图1-4-1: 4位宽度数据存储
无符号数表示范围:0 1 2 3 4 5 6 7 8 9 A B C D E F,箭头方向表示增加方向
有符号数:
正数表示范围:0 1 2 3 4 5 6 7
负数表示范围:-1 -2 -3 -4 -5 -6 -7 -8(从半圆F起到8,所以F表示-1,8表示-8)
无符号数不难理解,而有符号数则是从中间一分为二,左边为负数,右边为正数。同一个圆把它看成无符号数它是一个正数,如果把它看成是有符号数则是有正有负。比如F,它如果是无符号数,就是15,如果是有符号数它就是-1。
例2:我们再来看一下数据宽度为8位的数据储存情况,如图1-4-2所示:
图1-4-2:8位宽度数据存储
注释:4位宽度我们用1位十六进制表示,那么8位宽度就是2位十六进制。
无符号数的储存范围:0 1 2 3 ...FF。
我们用十进制来验证一下这个结果,8位2进制(相当于8条线,每一条线有通电和不通电两种情况),那它有28个,结果为256,我们将FF转化为十进制结果也是256。
有符号数储存范围:
正数:0 1 2 ...7F
负数:80 81 …FF
我们习惯使用十进制,很多书中在讲数据的存储范围的时候也是使用10进制,我们将上述有符号数转换为10进制,结果为-128~127。所以宽度为8位能存储的数据范围为:-128~127。
在我们程序中所看到内存的数据都是十六进制的,如果遇到有符号数,大家看到高位大于等于8的数就能想到它是负数。
例3、同样我们来看一下数据宽度为16位的数据存储情况,如图1-4-3所示:
图1-4-3:16位宽度数据存储
无符号数的存储范围:0~FFFF,转换为10进制范围为:(0 ~ 216 - 1)。
有符号数存储范围(8000~7FFF)
正数:0 ~7FFF
负数:-8000 ~FFFFF(-1)
例4、数据宽度为32位的数据存储情况,如图1-4-4所示:
图1-4-4:32位宽度数据存储
无符号数的存储范围:0~FF FF FF FF,转换为10进制范围为:(0 ~ 232 - 1)。
有符号数存储范围(80 00 00 00 ~ 7F FF FF FF)
正数:0 ~7F FF FF FF
负数:-80 00 00 00 ~ FF FF FF FF(-1)
宽度为32位是我们使用频率较多的一个容器,我们后面所学的寄存器就是32位。
总结:从计算机的角度来看,它并不区分什么是有符号数什么是无符号数,它只管存,但它最终表示的数值是我们如何定义和使用。
1.4.3【数据溢出】
所有的容器都是有界限的,一旦超出它的存储范围,它会从低位到高位存储,多余的会舍弃。
在计算机中,在对数值进行运算前要先规定其宽度,再进行运算。如果运算结果超过其宽度将被丢弃,只保留有效位。
例如:用32位宽度的容器计算无符号数FFFF FFFF+1=?因为该容器只能存储8位十六进制的数,而FFFF FFFF+1会进位变成9位十六进制数,等于1 0000 0000。这时候容器会舍掉高位,为8个0。图1-4-4中更形象地表示了这个结果:从0开始沿着箭头方向是增加的,FFFFFFFF的下个数为是0。
如果把FFFF FFFF看成有符号数,即为-1,-1+1 = 0,图1-4-4中FFFFFFFF的下个数为0。所以数据是无符号数还是有符号数关键在于我们怎么看,和计算机没有关系。
1.4.4【进制的符号】
十六进制符号用字母“0x”表示,如0xF8;二进制符号用“B”表示,如果11B。
1.4.5【容器的种类】
我们虽然可以根据数据的大小选择容器的宽度,但这并不是随意。计算机为我们提供四种单位的容器:
①字节(BYTE):数据宽度为8位;
②字(WORD):数据宽度为16位;
③双字(Doubleword,简写:DWORD):数据宽度为32位;
④ 四字(Quadword):数据宽度为64位。
图1-4-5显示了计算机常用的数值宽度,它们的高低位分布如图所示:
图1-4-5 计算机数值宽度