zoukankan      html  css  js  c++  java
  • 算术右移 逻辑右移

    先由一道题目引入:有两个变量a和b,不用if、?:、switch等判断语句,找出较大的那个变量。

    其中一种答案如下:

    char* result[] = {"a is larger", "b is larger"};
    int c = a - b;
    c = unsigned(c) >> (sizeof(int) * 8 - 1);
    cout << result[c] << endl;
    

     sizeof(int) * 8 很好理解,就是求出int型占内存的bit数,-1就是为了右移后保留最高位,即保留符号位。

     问题来了:为什么移位时要把c转为unsigned呢?而一旦去掉unsigned关键字的话运行出错。

     在vc2008中设置断点,调试,进入反汇编,发现问题出现在 >> 时,如果c为-1,则EAX(32位寄存器) = 0xffffffff,没有unsigned情况下移位后还是0xffffffff。

    //c = c >> (sizeof(int) * 8 - 1);
    004114F3  mov         eax,dword ptr [c] 
    004114F6  sar         eax,1Fh 
    004114F9  mov         dword ptr [c],eax 
    

     而有unsigned的话移位后则为0x00000001。

    //c = unsigned(c) >> (sizeof(int) * 8 - 1);
    004114F3  mov         eax,dword ptr [c] 
    004114F6  shr         eax,1Fh 
    004114F9  mov         dword ptr [c],eax 
    

     c右移的规则是:无符号数右移时左边高位移入0;有符号数右移时:1.符号位为0,移入0;2.符号位为1,有的系统移入1(算术右移),有的系统移入0(逻辑右移)

     经验证vc和gcc均默认为算术右移,上面的汇编代码也说明了这一点,有unsigned时右移采用的是shr(shift logical right)逻辑右移,无unsigned时采用sar(shift arithmetic right)算术右移。

     《c和指针》中也建议不要对有符号数进行>>操作,所以为了确保结果一定,>>时把数值转成unsigned

     又试了一下<<,发现signed和unsigned都是采用shl逻辑左移,应该是shl和sal效果都一样,所以编译器就统一采用shl。

     试验int 0x80000000 << 1结果为0,说明符号位对左移没影响。

  • 相关阅读:
    angular-ui-bootstrap的弹出框定义成一个服务的实践(二)
    分享百度文件上传组件webUploader的使用demo
    display的flex属性使用详解
    数组去重(初识ES6)
    在ng中的select的使用方法的讲解
    安装xamp之后,appach、mysql等问题的总结
    python中string.casefold和string.lower区别
    python3数据类型
    MySQL bin-log 日志清理方式
    python终端颜色设置
  • 原文地址:https://www.cnblogs.com/jacobchen/p/2497983.html
Copyright © 2011-2022 走看看