07. C Pro 关于正码/反码/补码

一、正负数的表示:

计算机只能存储01,正负数的存储有别!以最高位作为符号位:0=正数,1=负数!

正数的原码==反码==补码:

  EG:10 =》 0000 1010

负数的原码,即将其正数表示的符号位,改为1:

  EG:-10 =》 1000 1010

负数的反码,即其原码的符号位不变,其他位取反:
  EG:-10 =》 1111 0101

负数的补码,即反码 + bit(1):

  EG:-10 =》 1111 0101 + 0000 0001 = 1111 0110

 

二、任何数据都是以其二进制的补码形式存储在内存中的:因为计算机中只有加法没有减法,补码存储的数据其计算效率最高

下面我们看一个例子 这个例子也是我看的时候特别能帮助我理解的 清晰明了,例如 :

     3 - 2; 这个减法运算对于计算机而言它的理解是 3 + (-2) = 1

    使用原码计算:

    3的原码    00000000 00000000 00000000 00000011

    -2的原码   10000000 00000000 00000000 00000010

                ----------------------------------------------------

                   10000000 00000000 00000000 00000101   =》结果是1个负数明显是不对的

    使用反码计算:

    3 的反码:  00000000 00000000 00000000 00000011

    -2的反码:  11111111 11111111 11111111 11111101

                   --------------------------------------------------

                   00000000 00000000 00000000 00000000        =》0

    使用补码计算:

    3 的补码:   00000000 00000000 00000000 00000011

    -2的补码:   11111111 11111111 11111111 11111110

                   -------------------------------------------------

                    00000000 00000000 00000000  00000001       =》1

 

三、打印负数的补码,摘自:https://blog.csdn.net/wyt734933289/article/details/72889835

一个数的右移==算术右移,数学上表示除以2:如果是有符号数,对打印其 bit 不利,应先转为无符号数!

void main() {
  int num[20], cnt = 0;
  short a = -10;
  unsigned short b = a;
  while (b) {
    num[cnt++] = b & 1;  // 从最右边开始取位
    b >>= 1;       // 右移一位 == %2  =》左移== *2
  }
  for (int i = cnt - 1; i >= 0; i--)
    printf("%d ", num[i]);  // 倒叙输出
}

 

四、位运算

1.(int a) & 0x[0 | FF | xx] :将指定位清零,或者获取指定位!

2.(int a) | 0x[0 | FF | xx] :设定指定位=0|1;

3.(int a) ^ 0x[0 | FF | xx] :定位翻转,或者数值交换!

EG:要获取一个无符号数中从第 p 位开始的 n 位二进制数据(数据右端对齐)

unsigned int getbits(unsigned int x, unsigned int p, unsigned int n) {
  unsigned int a, b;
  a = x >> (p + 1);   // a 右移 p+1 位(位计数从0开始)
  b = ~(~0 << n);    // ~0=全1,左移 n 位,再取反 == 右侧 n 位 1
  return a & b;
}

 

上一篇:12C新功能:在线移动分区 (Doc ID 1584032.1)


下一篇:JS中的call、apply、bind方法详解