计算机中的有符号数和无符号数

来源:互联网 发布:淘宝二级页面打不开 编辑:程序博客网 时间:2024/04/29 23:45

1.概念
 在计算机中,可以区分正负类型的数,成为“有符号数”(signed);无正负类型的数(只有整数类型),成为“无符号数”(unsigned)。简明的说,无符号说就是其所有的位数都用来表示数值的大小,有符号数除最高位来表示数值的正负外(0表示正数;1表示负数),其余各位用来表示数值的大小。举个例子说明一下:十机制数 正数255  二进制表达形式:1111 1111

十机制数 负数-1     二进制表达形式:1111 1111 

可见-1的二进制的最高位为红色的1,可是为什么其表达形式为1111 1111而不是1000 0001呢?这就关于任何数在计算机内是以补码形式存储问题。下面会介绍的,在此先不详细说明了。

2.存储范围

从前面的介绍可以知道,由于有符号数的最高位被拿来用作符号位,所以它所能够表达的最大数值要小于无符号数所能够表达的最大数值。还是举个例子来说明一下吧:

无符号数:1111 1111 十进制值:255

有符号数:0111 1111 十进制值:127

这是有人可能会提出这样的疑问:有符号数所能够表达的数值范围会不会小于无符号数所能够表达的数值范围呢?

呵呵,答案是否定的!虽然有符号数在表达最大值上的能力减弱了,但是它能够表达负数。负数的个数可以弥补其不足。来让我们比较一下:

一个字节的无符号数的表达数值范围是:[0,255]

一个字节的有符号数的表达数值范围是:[-128,0),[0,127]

可见它们都能够表示256个数。

3.各种码(原码/反码/补码)

有些人也许会这样认为"-1"(双字节)在计算机中的表达形式为1000 0000 0000 0001,可是实际上不是的。计算机是以其补码的形式进行表达的,即“-1”(双字节)的表达形式是1111 1111 1111 1111。

说一下各种码的概念吧。

原码:一个整数,按照绝对值的大小转换成二进制数,最高位为符号位。

反码:将原码除最高位(符号位)外,其余各位按位取反,所得到的二进制码。正数的反码为原码。

补码:反码最低位加1即为补码。

关于负数的补码求法说明一下,先得到其反码,之后将反码加1即可。有些大神根据其原码,闭眼即得,这种能力需要修炼一下啊。

这时有些人可能会说,为什么要引入补码的形式呢?直接按照原码存储不就省事很多吗?嘿嘿,要记住,有些事情并不是你想省事就能省事的。好了来欣赏一下补码的优势吧。

计算机的带符号数用补码表示的优点:

1负数的补码与对应正数的补码之间的转换可以用同一种方法-求补运算完成,可以简化硬件。 2 可将减法变为加法,这样减法就可以用加法器进行计算了。 3 两个用补码表示的数相加时,如果最高位(符号位)有进位,则进位被舍弃。

心算求补(大神求补算法):

从最低位开始至找到的第一个1均不变,符号位不变,这之间的各位“求反”(0变1;1变0)。

原码:1010 1001  补码:1101 0111.

4.有符号数与无符号数的相互转换

无符号整数和有符号整数之间进行强制类型转换时,位模式不改变。

有符号数转换为无符号数时,负数转换为大的正数,相当于在原值上加上2的n次方,而正数保持不变。

无符号数转换为有符号数时,对于小的数将保持原值,对于大的数将转换为负数,相当于原值减去2的n次方。

当表达式中存在有符号数和无符号数类型时,所有的操作都自动转换为无符号类型。可见无符号数的运算优先级高于有符号数。

unsigned int a = 20;signed int b = -130;

 运算一下结果是 b>a 。

5.转换大餐

有符号数的转换

原类型目标类型转换方法 char

short

符号位扩展charlong符号位扩展charunsigned char最高符号位失去位意义,变为数据位charunsigned short符号位扩展到short;然后从short转到unsigned shortcharunsigned long符号位扩展到long;然后从long转换到unsigned longcharfloat符号位扩展到long;然后从long转到floatchardouble符号位扩展到long;然后从long转换到doublecharlong double符号位扩展到long;然后从long转换到long doubleshortchar保留低位字节shortlong符号位扩展shortunsigned char保留低位字节shortunsigned short

最高为失去意义,变为数据位

shortunsigned long符号位扩展到long;然后从long转到unsigned longshortfloat符号位扩展到long;然后从long转到floatshortdouble符号位扩展到long;然后从long转到doubleshortlong double符号位扩展到long;然后从long转换到long doublelongchar保留低位字节longshort保留低位字节longunsigned char保留低位字节longunsigned short保留低位字节longunsigned long最高为失去意义,变为数据位longfloat使用单精度浮点数表示,可能失去精度longdouble使用单精度浮点数表示,可能失去精度longlong double使用单精度浮点数表示,可能失去精度

无符号数的转换

原类型目标类型转换方法unsigned charchar最高为作符号位unsigned charshort0扩展unsigned charlong0扩展unsigned charunsigned short0扩展unsigned charunsigned long0扩展unsigned charfloat转换到long;然后从long转换到floatunsigned chardouble转换到long;然后从long转换到doubleunsigned charlong double转换到long;然后从long转换到long doubleunsigned shortchar保留低位字节unsigned shortshort最高为作符号位unsigned shortlong0扩展unsigned shortunsigned char保留低位字节unsigned shortunsigned long0扩展unsigned shortfloat转换到long;然后从long转换到floatunsigned shortdouble转换到long;然后从long转换到doubleunsigned longlong double转换到long;然后从long转换到long doubleunsigned longchar保留低位字节unsigned longshort保留低位字节unsigned longlong最高位作符号位unsigned longunsigned char保留低位字节unsigned longunsigned short保留低位字节unsigned longfloat转换到long;然后从long转换到floatunsigned longdouble直接转换到doubleunsigned longlong double转换到long;然后从long转换到long double
0 0