优秀的编程知识分享平台

网站首页 > 技术文章 正文

编程|类型转换:目标类型的编码规则解码原类型的编码规则

nanyue 2024-12-20 17:46:21 技术文章 4 ℃

电子计算机内部一切数据(数值与非数值数据)与指令皆二进制编码。

数据与指令按预定编码规则编码,然后按预定编码规则解码。

如常见的编码方案有:

原码、反码、补码、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 = -1*pow(2,31); // 0x00 00 00 80 大端是 80 00 00 00 其中8的二进制是 1000
int d = -1*pow(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

    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串,按目标类型的编码规则做解码。

0.9的二进制编码:

-End-

Tags:

最近发表
标签列表