84669 orang belajar
152542 orang belajar
20005 orang belajar
5487 orang belajar
7821 orang belajar
359900 orang belajar
3350 orang belajar
180660 orang belajar
48569 orang belajar
18603 orang belajar
40936 orang belajar
1549 orang belajar
1183 orang belajar
32909 orang belajar
我尝试使用了1<<31,结果得到的值是int的最小值。。。这是为什么?
因为这里默认1是int类型。而你的编译环境下,int`是32位的。那么这个1的二进制表示为
1
类型。而你的编译环境下,
0000 0000 0000 0000 0000 0000 0000 0000 0001
左移32位后
1000 0000 0000 0000 0000 0000 0000 0000 0000
因为是int类型,也就是有符号的。所以第一位为符号位,这是一个负数。为什么是int的最小值,因为是使用的是补码表示的。
int
如果需要移出最大值,使用下面的方式
((unsigned int)-1) >> 1
因为-1的二进制表示就是0xffffffff。转为无符号类型再移位,就不会有符号位的影响。
-1
0xffffffff
int最大是2的31次方-1,1<<31超范围了,会从最小的负数倒着来
对于32位的int,左移31位会到最高位对于有符号数,最高位为符号位,0为正,1为负,所以就变成最小值了,具体原因可以看下int的存储方式
(1 << 31) - 1 :有符号int 的最大值(1 << 31) + 1 : 有符号int 的最小值
((unsigned int)1<<32)-1 :无符号int 的最大值0 : 无符号int 的最小值
我测试了一下:
#include <stdio.h> #define STR(x) #x #define PRINT(x) printf("hex: 0x%08x, dec: %12d, str: \"%s\"\n", x, x, #x ) int main(){ puts( "全 0 & 全 1" ); PRINT( 0 ); PRINT( -1 ); puts( "\n全 1 的左右 shift" ); PRINT( -1>>1 ); PRINT( -1<<1 ); puts( "\n减法优先级更高" ); PRINT( 1<<31-1 ); PRINT( 1<<30 ); puts( "\n怎么得到 int 的最大正数" ); PRINT( 0x7FFFFFFF ); PRINT( 1<<31 ); PRINT( ((unsigned)1<<31)-1 ); PRINT( (int)(((unsigned)1<<31)-1) ); PRINT( ((unsigned int)-1)>>1 ); PRINT( -1>>1 ); return0; }
编译:gcc test.c -o test,
gcc test.c -o test
运行:./test
./test
结果:
全 0 & 全 1 hex: 0x00000000, dec: 0, str: "0" hex: 0xffffffff, dec: -1, str: "-1" 全 1 的左右 shift hex: 0xffffffff, dec: -1, str: "-1>>1" hex: 0xfffffffe, dec: -2, str: "-1<<1" 减法优先级更高 hex: 0x40000000, dec: 1073741824, str: "1<<31-1" hex: 0x40000000, dec: 1073741824, str: "1<<30" 怎么得到 int 的最大正数 hex: 0x7fffffff, dec: 2147483647, str: "0x7FFFFFFF" hex: 0x80000000, dec: -2147483648, str: "1<<31" hex: 0x7fffffff, dec: 2147483647, str: "((unsigned)1<<31)-1" hex: 0x7fffffff, dec: 2147483647, str: "(int)(((unsigned)1<<31)-1)" hex: 0x7fffffff, dec: 2147483647, str: "((unsigned int)-1)>>1" hex: 0xffffffff, dec: -1, str: "-1>>1"
兄弟,把符号位去了是移30位
因为这里默认
1
是int类型。而你的编译环境下,
int`是32位的。那么这个
1
的二进制表示为左移32位后
因为是
int
类型,也就是有符号的。所以第一位为符号位,这是一个负数。为什么是int
的最小值,因为是使用的是补码表示的。如果需要移出最大值,使用下面的方式
因为
-1
的二进制表示就是0xffffffff
。转为无符号类型再移位,就不会有符号位的影响。int最大是2的31次方-1,1<<31超范围了,会从最小的负数倒着来
对于32位的int,左移31位会到最高位
对于有符号数,最高位为符号位,0为正,1为负,所以就变成最小值了,具体原因可以看下int的存储方式
(1 << 31) - 1 :有符号int 的最大值
(1 << 31) + 1 : 有符号int 的最小值
((unsigned int)1<<32)-1 :无符号int 的最大值
0 : 无符号int 的最小值
我测试了一下:
编译:
gcc test.c -o test
,运行:
./test
结果:
兄弟,把符号位去了是移30位