@TOC 1、整形在电脑中的原反补码 整形的数据有三种表示形式: 原码 反码 补码 各个表示形式可以相互转化,最高位表示符号位,1为负数,0为正数 正数: 原码=反码=补码 负数: 原码:
@TOC
1、整形在电脑中的原反补码
整形的数据有三种表示形式:
- 原码
- 反码
- 补码
各个表示形式可以相互转化,最高位表示符号位,1为负数,0为正数
正数:
原码=反码=补码
负数:
原码:将数据直接转化成二进制就是原码 反码:符号位不变,将原码进行取反 补码:对反码进行+1,或者直接对原码进行取反+1
演示:
int i = -10;
(最高位表示符号位,1为负数,0为正数)
10000000 00000000 00000000 00001010 原码
11111111 11111111 11111111 11110101 反码
11111111 11111111 11111111 11110110 补码
在电脑中存储数据时,一般采用的都是补码 原因如下:
- cpu只有加法器,面对数值运算的时候补码更方便
- 原码到补码相互转换,其运算过程是相同的,不需要额外的硬件电路
- 使用补码可以将符号位和数值域一起计算,计算比较简单
2、各类型数据运算的整形提升与截断
当遇到char类型的变量存放整形以及进行整形运算的时候将会遇到整形提升和截断
截断
因为每种类型的取值范围不同,所以一旦存储的值超过了取值范围,就会导致值溢出来了,这个时候就需要进行截断 @人生如叶 各种数据类型的取值范围(总结全)
例:
char a = 200
200的原码:00000000 00000000 00000000 11001000
但是因为char的取值范围是-128~127,只能取8个bit位
所以就只要了前面的8个bit位
所以实际上电脑里存在a里面的就是11001000
但是因为char是有符号的字符类型,所以最高位就是符号位
因为符号位是1,所以是负数,就要用负数的原反补码转换方式
补码取反+1得到原码
11001000 补码
10110111 反码
10111000 原码
所以a的原码的值就是 -(8+16+32) = -56
整形提升
假设我要以%d的形式去打印一个用char类型的变量,就会存在位数不匹配的问题,char类型是8个bit位,而%d要打印的int类型是32个bit位,为了匹配,char类型在打印的时候就要把位数凑够32个bit位 一般凑位数的方法是将多余的位用符号位去补充
例:
char a = 20;
printf("%d", a);
这个时候,因为类型的位数不匹配,就要把位数给凑够
但是在那之前,必须先把20存到a里面
20
因为20是正数,所以原反补码相同
00000000 00000000 00000000 00010100
因为是char,所以发生截断
00010100
此时a存着的补码就是:11101100
现要求将a以%d的形式打印
看看符号位,是0,所以高位补0;
补充后的结果就是:00000000 00000000 00000000 00010100
3、练习
建议:先独立思考后再看以下解析
- 练习1
char a = -128;
printf("%u\n", a);
- 练习2
unsigned char i = -20;
unsigned int j = 10;
printf("%d\n", i+j);
- 练习3
unsigned int i = 0;
for(i = 9; i >= 0; i--)
{
printf("%u\n", i);
}
分享到这里就结束了,如果本文哪里有错误,还请大家指出,请在评论区留言; 如果觉得有用的话,还请给个免费的赞,灰常感谢捏!
【文章出处:响水网站开发公司 http://www.1234xp.com/xiangshui.html 欢迎留下您的宝贵建议】