位运算之左移右移

晚上吃完饭后, 翻了一会书, 看到了书上的一个关于位运算的样例, 124 « 2, 最后的结果是496. 用程序运行了下,正确,然后手贱想着用笔算一下,结果死活算不出这个数…,不过最后终于给算出来了.

程序

c language:

#include <stdio.h>

int main(void){
    int num = 124;
    
    printf("num is %d, sizeof is %d, left shift 2 bit:%d", num, sizeof(int), num << 2);
    return 0;
}

输出

num is 124, sizeof is 4, left shift 2 bit: 496

go language:

    package main

    import (
        "fmt"
        "unsafe"
    )
    func main() {
    	var i int32 = 124

    	fmt.Println(i << 2, unsafe.Sizeof(int32(0)))
    }

输出

496 4

计算过程

  • 十进制转换成二进制

      2|124  0
      2|62   0
      2|31   1
      2|15   1
      2| 7   1
      2| 3   1
      2| 1   1
         0
    

这种除法好像是叫 短除法 来着,也忘了是怎么生成了,凑合一下吧,起码形似了.

所以 124 的二进制数据就是 1111100 (从下往上 余数).

另外,因为本机 int型占用的字节为4字节,即 4 byte = 4 * 8 bit = 32 bit.

所以 上面的二进制数据补全了就是00000000 00000000 00000000 01111100

  • 左移两位

    00000000 00000000 00000000 01111100

    左移两位就变成了

    00000000 00000000 00000001 11110000

  • 二进制转换成十进制

    计算方法为

    从右到左用二进制的每个数去乘以2的相应次方

    0 * 20 + 0 * 21 + 0 * 22 + 0 * 23 + 1 * 24 + 1 * 25 +1 * 26 + 1 * 27 + 1 * 28 = 496

右移同理,右移运算需要注意的是

如果数字是一个无符号数值,则用0填补最左边的n位。如果数字是一个有符号数值,则用数字的符号位填补最左边的n位。也就是说如果数字原先是一个正数,则右移之后再最左边补n个0;如果数字原先是负数,则右移之后在最左边补n个1.