不是盖的 发表于 2015-2-9 21:50:38

浅谈C语言的逻辑位移与算术位移


请问以下在   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%08xb=%#08x\r\n",a,b);a=a<<1;b=b<<1;printf("移位前a=0x%08xb=%#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 右移两位是    11100000 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 上传 http://www.dumenmen.com/static/image/common/rleft.gif http://www.dumenmen.com/static/image/common/rright.gif






jianhong_wu 发表于 2015-2-9 22:38:04

感谢你的分享和付出。

f晨星 发表于 2015-3-7 13:20:24

谢谢分享:lol
页: [1]
查看完整版本: 浅谈C语言的逻辑位移与算术位移