首页 > 编程知识 正文

c语言左移运算符怎么用,c语言左移和右移怎么算

时间:2023-05-06 19:32:30 阅读:205874 作者:4041

左移 int i=1; i=i<<2;//把i里面的值左移2位

1的2进制是
000…0001
(这里前面0的个数和int的位数有关,32位机器,gcc里有31个0),左移2位之后变成:
000…0100,
也就是10进制的4,所以说左移1位相对于乘以2的n次方(有符号数不完成适用,因为左移有可能导致变化,下面解析原因)

//需要注意的一个问题是int类型最左端的符号位和移动出去的情况,我们知道,int是有符号的整形数,左端的1位是符号为,即0为正1为负,那么用移位的时候就会出现溢出,如:int i=0x40000000;//16进制的40000000,为2进制的01000000...0000i=i<<1;//那么,i在移动1位之后就会变成0x80000000,也就是2进制的100000...0000,符号位被置1,起位全是0,变成了int类型所能表达的最小值,32为的int这个值是-2147483648,溢出,如果在接着把i左移1位会出现什么情况呢?在c语言都采用了丢弃最高位的处理方法,丢弃了1之后,i的值变成了0

左移里面一个比较特殊的情况是当左移动的位数超过该数值类型的最大位数时,编译器会用左移的位数区模类型的最大位数,如

int i=1,j=0x80000000;//设int为32位i=i<<33;//33%32=1 左移动1位,i变成2j=j<<33;//33%32=1 左移动1位,j变成0,最高为被丢弃

总之左移就是: 丢弃最高位,0补最低位

右移

右移对符号位的处理和左移不同,对于有符号整数来说,比如int类型,右移会保持符号位不变,例如

int i = 0x80000000;i = i >> 1; //i的值不会变成0x40000000,而会变成0xc0000000 就是说,符号位向右移动后,正数的话补0,负数补1,也就是汇编语言中的算术右移.同样当移动的位数超过类型的长度时,会取余数,然后移动余数个位.总之,在C中,左移是逻辑/算术左移(两者完全相同),右移是算术右移,会保持符号位不变.实际应用中可以根据情况用左/右移做快速的乘/除运算,这样会比循环效率高很多. -5>>3=-11111 1111 1111 1111 1111 1111 1111 10111111 1111 1111 1111 1111 1111 1111 1111其结果与 Math.floor((double)-5/(2*2*2)) 完全相同。-5<<3=-401111 1111 1111 1111 1111 1111 1111 10111111 1111 1111 1111 1111 1111 1101 1000 其结果与 -5*2*2*2 完全相同。5>>3=00000 0000 0000 0000 0000 0000 0000 01010000 0000 0000 0000 0000 0000 0000 0000其结果与 5/(2*2*2) 完全相同。5<<3=400000 0000 0000 0000 0000 0000 0000 01010000 0000 0000 0000 0000 0000 0010 1000其结果与 5*2*2*2 完全相同。-5>>>3=536870911 1111 1111 1111 1111 1111 1111 1111 10110001 1111 1111 1111 1111 1111 1111 1111无论正数、负数,它们的右移、左移、无符号右移 32 位都是其本身,比如 -5<<32=-5、-5>>32=-5、-5>>>32=-5。一个有趣的现象是,把 1 左移 31 位再右移 31 位,其结果为 -1。0000 0000 0000 0000 0000 0000 0000 00011000 0000 0000 0000 0000 0000 0000 00001111 1111 1111 1111 1111 1111 1111 1111对于10进制的数字,左移一位就是在末尾加上一个0,数值变大10倍。同理,对于二进制数字,左移一位是在末尾加上一个0,数值变大2被。所以 x << 3,x就变大 2^3 倍,就是 8*x右移同理 一般情况下你要乘或者是除以数字是2的次方的话都可以用的执行速度快

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。