独闷闷网

 找回密码
 立即注册
搜索
查看: 6011|回复: 2
打印 上一主题 下一主题
收起左侧

[原创] 浅谈C语言的逻辑位移与算术位移

[复制链接]
跳转到指定楼层
楼主
发表于 2015-2-9 21:50:38 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
请问以下在     VISUAL C++编译环境中结果是多少
#include <stdio.h>
void main()
{
printf("%d\r\n" ,(1<<15)>>15);
printf("%d\r\n" ,(1<<31)>>31);   
}
答案是   
            

你算对了吗???
       C语言的位移运算,按位移的方向,可分为左移与右移,按位移的性质可分为逻辑位移与算术位移。
      逻辑位移内容,是位与位之间的逻辑关系,其准则为:左移即高位溢出摒弃,低位腾空补零。右移低位溢出摒弃,高位腾空是补零。
      算术位移的内容是运算,如右移一位即除以2。
      当为左移运算时,无论左移的操作对象是有符号的整形数还是无符号的整形数,都是逻辑左移运算。即高位溢出摒弃,低位腾空补零。
如以下代码
#include <stdio.h>
void main()
{
int a=0X80000000;        //最高位为1 负数
unsigned int b=0x00000001;   
printf("移位前  a=0x%08x  b=%#08x  \r\n",a,b);  
a=a<<1;
b=b<<1;
printf("移位前  a=0x%08x  b=%#08x  \r\n",a,b);   
}

其运行结果为
                    

         大家注意到了没有,负数a左移移位之后结果为0,符号位溢出摒弃,这里不是算术位移,而是逻辑位移。
         当为右移运算时,则要根据数据的类型,当操作对象是无符号整形数时,则是逻辑右移,即所谓的
高位腾空补零,低位溢出摒弃。  
        而操作对象是有符号整形数,这时大家注意了,大多数编译器是做算术位移处理的。低位溢出摒弃,
高位腾空是补零或是1,则根据为数据的符号,如果是正数,补零,如果是负数,则是补一。
我们这里重点讨论一下有符号整形数的右移运算
#include <stdio.h>
void main()
{
int a=0x80000000;  //最高位为1,即为负数
int b=0x40000000 ;  //最高位为0,即为正数


printf("移位前....................\r\n");
printf("a=0x%08x  十进制表示%d\r\n",a,a);
printf("b=0x%08x  十进制表示%d\r\n",b,b);


   a=a>>1 ;  
   b=b>>1 ;

  printf("移位后....................\r\n");
  printf("a=0x%08x  十进制表示%d\r\n",a,a);
  printf("b=0x%08x  十进制表示%d\r\n",b,b);


}
其运算结果为
                        
负数a右移一位,做算术位移,高位补1。移位之后满足算术逻辑   a=-2147483648/2=-1073741824
正数b右移一位 做算术位移,高位补0 。b=1073741824/2=536870912
   不知道大家看到这里,本文章一开始的代码大家能解释了吗.编译器整形数默认是int
   printf("%d\r\n" ,(1<<15)>>15);结果为0相信很好解释,左移15位,最高位是0,正数,右移15位,高位补0,结果还是1
    printf("%d\r\n" ,(1<<31)>>31);先是做逻辑运算,左移31位,此时做高位是1,为负数,此时右移,做算术逻辑,高位补一
  右移一位是   1100 0000 0000 0000 0000 0000 0000  
右移两位是    1110  0000 0000 0000 0000 0000 0000
  .........................
右移31位是   1111 1111 1111 1111 1111 1111 1111
  大家知道,因为负数的原码最高位符号位不能直接参与运算,为避免额外的硬件开销,负数在计算机存储是以补码的形式存在的。
  他的原码是:补码保留符号位不变,其他数取反加1,即 1000 0000 0000 0000 0000 0000 0000 0001即-1的源码,
  验证了我们的结果。个人见解,多多指教{:soso_e113:}。











3.png (10.49 KB, 下载次数: 0)
下载附件  保存到相册
昨天 21:23 上传






乐于分享,勇于质疑!
沙发
发表于 2015-2-9 22:38:04 | 只看该作者
感谢你的分享和付出。
乐于分享,勇于质疑!
板凳
发表于 2015-3-7 13:20:24 | 只看该作者
谢谢分享
乐于分享,勇于质疑!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|独闷闷网 ( 粤ICP备12007667号-2 )

GMT+8, 2024-4-26 06:55 , Processed in 0.176263 second(s), 19 queries .

快速回复 返回顶部 返回列表