电子计算机内部一切数据(数值与非数值数据)与指令皆二进制编码。
数据与指令按预定编码规则编码,然后按预定编码规则解码。
如常见的编码方案有:
原码、反码、补码、IEEE754编码方案、ASCII、GB2312、unicode、jpeg、png、mp3、rmvb、mp4等。
当类型不同时,可能存在截断,溢出、整型提型等特殊情形。
当利用指针进行类型转换时,即是利用目标类型来解释现在二进制01串。
1 整数的补码
如果x + y(x的补码) = 模,则称x和y互补。如机械表盘划分12个刻度表示为12小时,其模就是12,我们看时间时,逆时钟看到时针在第3个刻度的位置,我们就知道时间是12-3=9点了。
对于十进制:
如果是个位数,模就是10;
如果是两位数,模就是100;
如果是n位数,模就是10^n;
对于二进制:
如果是一个字节,模就是0x100,对应十进制是2^8=256
15 0x0F
241 0xF1
两者相加:
256 0x001
对于一个字节来说,其241的编码就相当于-15。
int a = 11; // 0x0B 00 00 00 大端是 00 00 00 0B 其中B的二进制是 1011
int b = -11; // 0xF5 FF FF FF 大端是 FF FF FF F5 其中5的二进制是 0101
// 0x0B+0xF5 = 0x100
int c = -1pow(2,31); // 0x00 00 00 80 大端是 80 00 00 00 其中8的二进制是 1000
int d = -1pow(2,31)+11;// 0x0B 00 00 80 大端是 80 00 00 0B 其中B的二进制是 1011,十进制的11
int e = -1; // 0xFF FF FF FF 大端是 FF FF FF FF
对于补码,-1 = 0-1,也就是FFFFFFFF,是最大的unsigned int。而对于-11,则是FFFFFFFF-10。
实例1
char a= -1;
signed char b=-1;
unsigned char c=-1;
printf("%d %d %d",a,b,c); // -1 -1 255
字面量-1怎样编码,对于32位系统而言,-1的类型是signed int,其二进制编码是:
0xFFFFFFFF
从4个字节的int到1个字节的char,需要截断。
对于0xFF,按照char和signed char的编码规则,解释(解码)这一串二进制位,都是-1。
而对于unsigned char,则要解码为255。
实例2
char a = 128; // 0x80 char的值域-128~127,128会溢出到符号位
char b = -128; // 0x80
char c = 12; // 0x0c
printf("%u %u %u\n",a,b,c);// 4294967168 4294967168 12
// 整型提升,填充符号位
实例3
int i= -20;
unsigned int j = 10;
printf("%d\n", i+j); //-10
//i提升为unsigned int,最后格式化为signed int
实例4
unsigned int i;
for(i = 9; i >= 0; i--) // 对于unsgined int,当其为0时,减1后,
// -1按unsgined int解码0xFFFFFFFF为4294967295
{
printf("%u\n",i);
}
对于unsigned int而言,不管如何运算,其结果永远大于等于0,所以以上循环构成死循环。
实例5
//代码效果参考:http://www.zidongmutanji.com/bxxx/332280.html
char a[1000];
int i;
for(i=0; i<1000; i++)
{
a[i] = -1-i;
}
printf("%d ",strlen(a)); // 255
char arr[] = "abcdef";
arr[3] = -256;
printf("%s",arr); // abc
当某一数据类型超出值域时,其数值等于模模后的结果。
实例6
unsigned char i = 0;
for(i = 0;i<=255;i++) // i的值域是0~255
{
printf("hello world\n");
}
因为i的值域是0~255,所以循环构成死循环。
2 浮点数编码规则
看以下代码:
int n = 9;
float pFloat = (float )&n;
printf("%d\n",n); // 9
printf("%f\n",pFloat);// 0.000000 pFloat = 9.0;
printf("%d\n",n); // 1091567616
printf("%f\n",*pFloat); // 9.000000
当通过指针做类型转换时,也就是对现有二进制01串,按目标类型的编码规则做解码。