[What]interger representations

重新认识计算机系统。

无符号整型编码

无符号整型使用的编码方式为 B2Uw(binary to unsigned, length w),其公式为:

b2uw_equation.jpg
  • w 代表整数一共有w位
  • xi 分别代表每一位的索引
  • 可表示的范围为 0 ~ 2w - 1

所以上面的意思就是说,无符号整数可以通过每一位的值乘以一个2的n次方总和来表示。

  • 任何一个非负整数都可以表示为2的n次方的和,这让我想到了linux kernel 中的buddy算法。
B2U4([0111]) = 0*2^3 + 1*2^2 + 1*2^1 + 1*2^0 = 0 + 4 + 2 + 1 = 7

补码编码

有符号整型的编码方式为B2Tw(binary to two's complement length w),其公式为:

b2tw_equation.jpg
  • 可表示的范围为 -2w-1 ~ 2w-1 - 1

代表符号位的负数,再加上其他位的2的n次方总和:

B2T4(1011) = -1 * 2 ^ 3 + 0 * 2 ^ 2 + 1 * 2 ^ 1 + 1 * 2 ^ 0 = -8 + 0 + 2 + 1 = -5 

c中无符号与有符号之间的转换

  • 当二者位数一致时,那么其在内存中二进制是一样的,只是解释形式不一致罢了
  • 当被赋值的位数小于数据时,会做二进制截断
    • 当无符号数截断到无符号数时,就是做求余数操作
    • 当无符号数截断到有符号数时,先做求余操作到无符号,再转换到有符号
    • 当有符号数截断到有符号或无符号时,先将有符号转为无符号再进行前两步操作
  • 当被赋值的位数大于数据时,会 先做二进制扩展,再赋值
    • 非负数直接增加0即可
    • 负数则按照增加1的方式扩展
  • c中的数值都默认为是有符号整数,当数值后加 uU 才指定为无符号整数.
    • 需要注意的是: 当有符号常量与无符号常量进行比较时,有符号数会先以无符号解释再来进行比较
#include <stdio.h>
#include <stdint.h>

int main(char argc, char**argv)
{


if(-1 < 1u)
{
printf("-1 < 1\n");
}
else
{
printf(" -1 > 1\n");//最终会走这条路径!
}


return 0;
}

在进制表示中,可以得出有符号到无符号转换的规律:

/**
* 当数值为非负数,则返回其本身,否则返回其本身与最大数值之和
*
* @ex: T2U16(-12345) = -12345 + 2^16 = 53191
*/

if(x >= 0)
{
return x;
}
else
{
return ( x + pow(2, w))
}

同理无符号到有符号转换规律如下:

if(x <= Tmax) //Tmax 即为有符号型能表示的最大值, 2^(w -1) -1
{
return x;
}
else
{
return (x - pow(2, w));
}
Last Updated 2018-10-14 日 19:32.
Render by hexo-renderer-org with Emacs 26.1 (Org mode 9.1.14)