实际应用中可以根据情况用左/右移做快速的乘/除运算,这样会比循环效率高很多
- i为0x80000000,也就是2进制的100000...0000(共31位,有一个1个符号位),符号位被置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变成2 j = j << 33; // 33 % 32 = 1 左移1位,j变成0,最高位被丢弃
- 负数是用补码表示的,正数的原码与补码相同,所以不用考虑补码的事。例如-3 :1...11111101
- C标准并没有明确地指定是使用逻辑右移还是算术右移。但大多数的机器都使用算术右移
算术、逻辑移位
算术右移:最高位填充符号位。正数填充0,负数填充1
逻辑右移:最高位填充0。可以想象成无符号,都是正的都是0
左移都是补0