注意:
无符号数、正数, 他们的原码 == 反码 ==补码
负数:反码 == 原码的符号位不变 其他位 取反
补码 = 反 + 1
(重要):负数在计算机储存的是补码
计算机为什么要补码?
如果没有补码:
6-10 == -4
6+(-10) = -4
0000 0110
1000 1010
-------------
1001 0000 == -16(错误)
如果要补码:
0000 0110
1111 0110
-------------
1111 1100 ------》1000 0011 ------》1000 0100 ------》-4
总结:补码的意义 将减法运算 变加法运算
以1字节分析:
有符号数:1111 1111 ~ 1000 0000 ~ 0000 0000 ~ 0111 1111
-127 ~ -0 ~ +0 ~ +127
计算机为了扩展数据的表示范围:故意将-0看成-128
-128~127
无符号数:0000 0000 ~ 1111 1111 == 0~255
总结:补码统一0的编码。
+0 == 0000 0000 == 0000 0000(反码)== 0000 0000(补码)
-0 == 1000 0000 == 1111 1111(反码)== 0000 0000(补码)
总结:补码的意义将减法运算 变加法运算 同时统一了0的编码。
计算机对数据的存储与读取
储存案例:
#include<stdio.h>
void test01()//存储
{
//负数以补码存储
char data = -10;
//正数以原码存储
char data2 = 10;
//十六进制以原码储存
char data3 = 0xae; //0xae == 1010 1110
//八进制以原码储存
char data4 = 0256;
//每三位二进制 代表 一位八进制
//如果数据越界 以原码储存
char data5 = 129;//1000 0001
unsigned char data6 = -10;
//取 %x %u %o 都是输出内存的原样数据
//每4位二进制表示 一位十六进制(记住)
printf("%x\n",data); //0xf6
printf("%x\n",data2);//0xae
printf("%x\n",data3);//0xae
printf("%x\n",data4);//0xae
printf("%x\n",data5);//0x81
printf("%x\n",data6);//0xf6
return;
}
int main(int argc,char *argv[])
{
test01();
return 0;
}
取案例:
#include<stdio.h>
void test02()
{
char data1 = -10;
//%d %ld %hd 有符号取 ,%u %x %o %lu 无符号取
//有符号取
//首先看内存的最高位如果为1 取内存数据符号位不变取反+1得到原码
//如果最高位为0 将数据原样输出
//无符号取
//将内存数据原样输出
printf("%d\n",data1);//-10
printf("%u\n",data1&0x000000ff);//data1&0x000000ff 只取低八位 输出:246 == 1111 0110
return;
}
int main(int argc,char *argv[])
{
test02();
return 0;
}
|