以int为4字节为例
unsigned int 0的二进制表示为(后面解释为什么用unsigned int)
00000000 00000000 00000000 00000000
那么对其取反得:
11111111 11111111 11111111 11111111
因为int型第32位为符号位,所以要对上数右移一位,既得:
01111111 11111111 11111111 11111111
即2147483647
最小值即对上数再进行取反,得:
10000000 00000000 00000000 00000000
即-2147483648
代码如下:
int main(int argc, char *argv[])
{
int a=(~(unsigned int)0)>>1;
printf("max:%d\nmin:%d \n",a,~a);
system("PAUSE");
return 0;
}
13年8月11日
补充:
关于为什么要用unsigned int 0来进行操作:
这涉及到两个概念,逻辑右移和算数右移
所谓逻辑右移就是,空缺的高位补零。
所谓算术右移就是,要保持符号位不变。
如果使用 unsigned int 0来进行初始操作,则没有符号位,右移操作是逻辑右移。
如果使用int 0来进行初始操作,则最高位是符号位,而有符号数的>>操作是编译器相关的。
即不同编译器,有可能进行算术右移,也有可能进行逻辑右移。
另外,算术左移和逻辑左移是相同的,不要求保持符号位不变。
总结一下:
算术左移、逻辑左移、逻辑右移:空缺用0补。
算术右移:空缺用符号位补,即符号位自身回溯,保证正为正,负为负。
综上,由于>>操作的编译器相关导致的不确定性,《C和指针》建议,不要对有符号数进行>>操作。
另外,用cout输出十六进制和八进制,可用如下方式:
#include <iomanip>
cout<<setbase(16)<<a;
参数只支持8 16 10,其他参数视为10,自己试的,有错误请提出。