左移和右移

  1. 代码  
  2.   
  3. #include "stdio.h"  
  4.   
  5. char leftshift(char i, int n)  
  6. {  
  7.     if(n < 0)  
  8.         return -1;  
  9.     return i<<n;  
  10. }  
  11.   
  12. char rightshift(char i, int n)  
  13. {  
  14.     if(n < 0)  
  15.         return -1;  
  16.     return i>>n;  
  17. }  
  18.   
  19. int main()  
  20. {  
  21.     //leftshift  
  22.     char a1 = 127;  
  23.     char a2 = -1;  
  24.   
  25.     for(int i = 1; i <= 8; i++)  
  26.         printf("%d<<%d = %d;\n", a1, i, leftshift(a1,i));  
  27.   
  28.     for(i = 1; i <= 8; i++)  
  29.         printf("%d<<%d = %d;\n", a2, i, leftshift(a2,i));  
  30.   
  31.     //rightshift  
  32.     a1 = 127;  
  33.     a2 = -128;  
  34.   
  35.     for(i = 1; i <= 8; i++)  
  36.         printf("%d>>%d = %d;\n", a1, i, rightshift(a1,i));  
  37.   
  38.     for(i = 1; i <= 8; i++)  
  39.         printf("%d>>%d = %d;\n", a2, i, rightshift(a2,i));  
  40.   
  41.     return 0;  
  42. }  
代码

#include "stdio.h"

char leftshift(char i, int n)
{
    if(n < 0)
        return -1;
    return i<<n;
}

char rightshift(char i, int n)
{
    if(n < 0)
        return -1;
    return i>>n;
}

int main()
{
    //leftshift
    char a1 = 127;
    char a2 = -1;

    for(int i = 1; i <= 8; i++)
        printf("%d<<%d = %d;\n", a1, i, leftshift(a1,i));

    for(i = 1; i <= 8; i++)
        printf("%d<<%d = %d;\n", a2, i, leftshift(a2,i));

    //rightshift
    a1 = 127;
    a2 = -128;

    for(i = 1; i <= 8; i++)
        printf("%d>>%d = %d;\n", a1, i, rightshift(a1,i));

    for(i = 1; i <= 8; i++)
        printf("%d>>%d = %d;\n", a2, i, rightshift(a2,i));

    return 0;
}


结果为:

  1. 结果  
  2.   
  3. 127<<1 = -2;  
  4. 127<<2 = -4;  
  5. 127<<3 = -8;  
  6. 127<<4 = -16;  
  7. 127<<5 = -32;  
  8. 127<<6 = -64;  
  9. 127<<7 = -128;  
  10. 127<<8 = 0;  
  11.   
  12. -1<<1 = -2;  
  13. -1<<2 = -4;  
  14. -1<<3 = -8;  
  15. -1<<4 = -16;  
  16. -1<<5 = -32;  
  17. -1<<6 = -64;  
  18. -1<<7 = -128;  
  19. -1<<8 = 0;  
  20.   
  21. 127>>1 = 63;  
  22. 127>>2 = 31;  
  23. 127>>3 = 15;  
  24. 127>>4 = 7;  
  25. 127>>5 = 3;  
  26. 127>>6 = 1;  
  27. 127>>7 = 0;  
  28. 127>>8 = 0;  
  29.   
  30. -128>>1 = -64;  
  31. -128>>2 = -32;  
  32. -128>>3 = -16;  
  33. -128>>4 = -8;  
  34. -128>>5 = -4;  
  35. -128>>6 = -2;  
  36. -128>>7 = -1;  
  37. -128>>8 = -1;  
结果

127<<1 = -2;
127<<2 = -4;
127<<3 = -8;
127<<4 = -16;
127<<5 = -32;
127<<6 = -64;
127<<7 = -128;
127<<8 = 0;

-1<<1 = -2;
-1<<2 = -4;
-1<<3 = -8;
-1<<4 = -16;
-1<<5 = -32;
-1<<6 = -64;
-1<<7 = -128;
-1<<8 = 0;

127>>1 = 63;
127>>2 = 31;
127>>3 = 15;
127>>4 = 7;
127>>5 = 3;
127>>6 = 1;
127>>7 = 0;
127>>8 = 0;

-128>>1 = -64;
-128>>2 = -32;
-128>>3 = -16;
-128>>4 = -8;
-128>>5 = -4;
-128>>6 = -2;
-128>>7 = -1;
-128>>8 = -1;

左移操作(<<)
规则:
右边空出的位用0填补
高位左移溢出则舍弃该高位。
计算机中常用补码表示数据:
数据 127,补码和原码一样:0111 1111。
左移一位: 1111 1110   -> 这个补码对应的原码为:1000 0010  对应十进制:-2
左移二位: 1111 1100   -> 这个补码对应的原码为:1000 0100  对应十进制:-4
左移三位: 1111 1000   -> 这个补码对应的原码为:1000 1000  对应十进制:-8
左移四位: 1111 0000   -> 这个补码对应的原码为:1001 0000  对应十进制:-16
左移五位: 1110 0000   -> 这个补码对应的原码为:1010 0000  对应十进制:-32
左移六位: 1100 0000   -> 这个补码对应的原码为:1100 0000  对应十进制:-64
左移七位: 1000 0000   -> 这个补码对应的原码为:1000 0000  对应十进制:-128
左移八位: 0000 0000   -> 这个补码对应的原码为:0000 0000  对应十进制:0
注:
原码到补码的计算方式:取反+1,
补码到原码的计算方式:-1再取反。
数据-1,它的原码为1000 0001,补码为1111 1111
左移一位: 1111 1110   -> 这个补码对应的原码为:1000 0010  对应十进制:-2
左移二位: 1111 1100   -> 这个补码对应的原码为:1000 0100  对应十进制:-4
左移三位: 1111 1000   -> 这个补码对应的原码为:1000 1000  对应十进制:-8
左移四位: 1111 0000   -> 这个补码对应的原码为:1001 0000  对应十进制:-16
左移五位: 1110 0000   -> 这个补码对应的原码为:1010 0000  对应十进制:-32
左移六位: 1100 0000   -> 这个补码对应的原码为:1100 0000  对应十进制:-64
左移七位: 1000 0000   -> 这个补码对应的原码为:1000 0000  对应十进制:-128
左移八位: 0000 0000   -> 这个补码对应的原码为:0000 0000  对应十进制:0
可以看出127和-1的结果完全一样。移位操作与正负数无关,它只是忠实的将所有位进行移动,补0,舍弃操作。
右移操作(>>)
规则:

左边空出的位用0或者1填补。正数用0填补,负数用1填补。注:不同的环境填补方式可能不同;

低位右移溢出则舍弃该位。

1、127的补码:0111 1111

右移一位: 0011 1111   -> 原码同补码一样  对应十进制:63

右移二位: 0001 1111   -> 原码同补码一样  对应十进制:31

右移三位: 0000 1111   -> 原码同补码一样  对应十进制:15

右移四位: 0000 0111   -> 原码同补码一样  对应十进制:7

右移五位: 0000 0011   -> 原码同补码一样  对应十进制:3

右移六位: 0000 0001   -> 原码同补码一样  对应十进制:1

右移七位: 0000 0000   -> 原码同补码一样  对应十进制:0

右移八位: 0000 0000   -> 原码同补码一样  对应十进制:0

2、-128的补码:1000 0000

右移一位: 1100 0000   -> 这个补码对应的原码为:1100 0000  对应十进制:-64

右移二位: 1110 0000   -> 这个补码对应的原码为:1010 0000  对应十进制:-32

右移三位: 1111 0000   -> 这个补码对应的原码为:1001 0000  对应十进制:-16

右移四位: 1111 1000   -> 这个补码对应的原码为:1000 1000  对应十进制:-8

右移五位: 1111 1100   -> 这个补码对应的原码为:1000 0100  对应十进制:-4

右移六位: 1111 1110   -> 这个补码对应的原码为:1000 0010  对应十进制:-2

右移七位: 1111 1111   -> 这个补码对应的原码为:1000 0001  对应十进制:-1

右移八位: 1111 1111   -> 这个补码对应的原码为:1000 0001  对应十进制:-1

常见应用
左移相当于*2,只是要注意边界问题。如char a = 65; a<<1 按照*2来算为130;但有符号char的取值范围-128~127,已经越界,多超出了3个数值,所以从-128算起的第三个数值-126才是a<<1的正确结果。
而右移相当于除以2,只是要注意移位比较多的时候结果会趋近去一个非常小的数,如上面结果中的-1,0。
其它的四种位运算:
与运算(&)
1、与0相与可清零
2、与1相与可保留原值
或运算(|)
1、与0相或可保留原值
2、与1相与可齐设1
异或运算(^)
1、与0异或保留原值
2、与1异或比特值反转
3、可通过某种算法,使用异或实现交换两个值
异或运算是有结合律的
取反(~)

转载地址:http://www.cnblogs.com/yyangblog/archive/2011/01/14/1935656.html


猜你喜欢

转载自blog.csdn.net/weixin_41573650/article/details/80727541