-
整数的表示
在C语言里,整数的取值范围主要是以下两张图:
捕获.PNG
捕获1.PNG
同时可以看出,负数的范围比正数的范围大1。(C和C++都支持有符号数(默认)和无符号数,Java只支持有符号数) -
有符号数编码
有符号整数的编码方式主要有三种,分别是原码、反码和补码。
① 原码:
原码是指将最高位作为符号位(0表示正,1表示负),其它数字位代表数值本身的绝对值的数字表示方式。
例如数字6 在计算机中原码表示为:0 000 0110
其中,第一个数字0是符号位,0表示正数,0 000110是数字6的二进制数据表示。
数字-6 在计算机中原码表示为:1 000 0110
以上是在8位计算机中的原码表示,如果在32位或16位计算机中,表示方法也是一样的,只是多了几个数字0而已。
例如,在32位 计算机中数字6 的原码表示为:00000000 0000 0000 0000 0000 0000 0110
在16位 计算机中数字6 的原码表示为:00000000 0000 0110
② 反码:
反码表示规则为:如果是正数,则表示方法和原码一样;如果是负数,符号位不变,其余各位取反,则得到这个数字的反码表示形式。
例如,数字6 在8位 计算机中的反码就是它的原码:00000110
数字-6 在 8位计算机中的反码为:11111001
③ 补码
补码是计算机表示有符号数的一般方式,其规则为:如果是正数,则表示方法和原码一样;如果是负数,则在该数字的反码加上1(相当于将原码数值位取反然后在最低位加1)。
例如:数字6 在8位 计算机中的补码就是它的原码:00000110
数字-6 在8 位 计算机中的补码为:1111 1010
总结一下:无符号数只能表示非负整数,它的编码就是将其转换成对应的二进制来表示即可。有符号数的编码方式有三种,分别是原码、反码和补码。正数的反码和补码与它的原码一样,绝大多数机器都是采用补码来表示有符号数。
对于大多数C语言实现,处理同样字长的有符号数和无符号之间转换的一般规则是:数值可能会变,但位模式不会变(底层的补码没变),如下:
int tx,ty;
unsigned ux,uy;
tx=ux;
uy=ty;
同时,无符号数的优先级要大于有符号数,如果无符号和有符号数进行比较和赋值,则均转化为无符号数,如下:
unsigned int i = 5;
int j = -10;
此时,i+j为unsigned int。
-
扩展一个数字的位表示
一种常见的运算是在不同字长的整数之间进行转换,同时又保持数值不变。
要将一个无符号数转换成一个更大的数据类型,只需简单的在它的编码前面添0即可,称为零扩展。
因为绝大多数有符号数都是用其补码来表示的,所以有符号数的扩展即是其补码的扩展,也很简单,在它的编码前面增加符号位即可,称为符号扩展。
另外一提的是,当即要改变一个数字的有无符号和数据大小时,先要改变大小,再改变有无符号的情况,这是C语言标准要求的。 -
截断数字
顾名思义,就是将高位的数字截成低位数字。不过有一点需要注意,无符号数字的截断比较简单,丢弃高位即可;有符号数在截断后,还要注意它的符号位可能会变化。
int a = 233;
char b = (char)a;
printf("%d",b);
网友评论