C语言中位移运算详解(精髓:内存存放补码)

左移: 无论是有符号数,还是无符号数,左移动都是向左移动, 高位丢弃,低位补0.

例如:

unsigned char x = 0x34;    ----->二进制数:0011 0100

内存中的形式为:0011 0100 

X<<1 ==>  移位前:0011 0100

                    移位后:0110 1000    ----->0x68    ----->十进制数:104



右移:右移分为以下两类
一、逻辑右移(针对无符号数):   向右移动,高位补 0 ,低位舍弃。

例如:

unsigned char x = 0x34;==》二进制数:0011 0100

内存中的形式为:0011 0100

X >> 1  移位前:0011 0100

             移位后:0001 1010    ------>0x1a    ------>十进制数:26

 

二、算术右移(针对有符号数):正数,向右移动,高位补 0 ,低位舍弃。

                                                   负数,向右移动,高位补1,低位舍弃。

正数: (正数的补码就是原码)

char  x = 3——>二进制数:0000 0011

       内存中的形式为:0000 0011

X >> 1                     移位前:0000 0011

                                移位后:0000 0001    ———>0x1    ——>十进制数:1



负数:(负数的补码是符号位不变,各位取反加一)

char x = -3//3的二进制数位 0000 0011,-3最高位为1.

        则-3的原码:1000 0011

            反码:   1111 1100

            补码:1111 1101 (内存中存的是补码) 

           故在内存中的存储方式为:1111 1101

X >> 1;                 向右移动,高位补1

            移动前:1111 1101

            移位后:1111 1110

     移位后内存补码为:1111 1110

我们若是printf打印数据,就要读取内存。需要把补码转换成反码来查看。即。

补码:1111 1110  (最高位为1,是负数,对补码求补码的原码

反码:1000 0001

原码:1000 0010===-0x2===>-2

 

你可能感兴趣的:(Linux)