编码规则
不同的文件有不同的编码规则
例如:
01010101
转换为16进制为
55
这里如果当作有符号数来判断,那么01010101转换为16进制仍然为55,原因很简单:
- 若字节最高位以1开头,那么值为负。
- 若字节最高位以0开头,那么值为正。
例如:
11010101 //这里当无符号数转换
转换为16进制为:0xD5
转换为10进制为:213
那么当有符号数判断时是-213么,答案是:不是。
有符号数的编码规则
原码:最高位为符号位,其余各位为数值本身的绝对值
反码:
正数:反码与原码相同
负数:符号位为1,其余为与原码取反
补码:
正数:补码与原码形同
负数:符号位为1,其余与原码取反并加1
举例说明
这里数据宽度我们用字节(8bit)来计算
数字 | 原码 | 反码 | 补码 |
---|---|---|---|
1 | 00000001 | 00000001 | 00000001 |
6 | 00000110 | 00000110 | 00000110 |
-1 | 10000001 | 11111110 | 11111111 |
-7 | 10000111 | 11111000 | 11111001 |
光这么看可能不是很好理解,我们直接写个小程序到反汇编里看一下。
#include <stdio.h> //头文件
void main() //程序入口
{
char x = 1; //把1赋给x并以char类型储存
printf("%x\n",&x); //输出所在结果的堆栈地址
return; //程序结束
}
运行一下,看看结果存到了哪里:
去堆栈中查一下这个以16进制储存的结果是什么:
结果为01,那么01转二进制就很简单了,是00000001刚好与上表中1的原码对起来。
我们继续传一个-1看看它在堆栈中的16进制结果:
#include <stdio.h> //头文件
void main() //程序入口
{
char x = -1; //把-1赋给x并以char类型储存
printf("%x\n",&x); //输出所在结果的堆栈地址
return; //程序结束
}
运行结果:
这里还是12FF7F,我们去堆栈中查一下值:
这里是FF,转为二进制就是11111111,刚好与上表中-1的补码对应起来。
总结
- 正数在堆栈中以原码储存
- 负数在堆栈中以补码储存