4294967295 | 1 //-1
4294967295 二进制是 11111111111111111111111111111111 32位
1 是 00000000000000000000000000000001
那么按位或的结果应该还是 11111111111111111111111111111111
转化十进制也就是 4294967295
可结果就是 -1
哪位大佬解释下
4294967295 | 1 //-1
4294967295 二进制是 11111111111111111111111111111111 32位
1 是 00000000000000000000000000000001
那么按位或的结果应该还是 11111111111111111111111111111111
转化十进制也就是 4294967295
可结果就是 -1
哪位大佬解释下
这是计算机原理的范畴了,可以参考这个网址:https://www.zhihu.com/questio...
计算机中的负数是以其补码形式存在的 补码=原码取反+1
4294967295 二进制是
11111111111111111111111111111111 32位
第一位是符号位,4294967295的补码是
10000000000000000000000000000001
1 是
00000000000000000000000000000001
取或后
10000000000000000000000000000001 = -1
你没有贴代码,但是打了 Java 的标签所以我这边进行了下尝试:
代码:
System.out.println(4294967295L | 1);
System.out.println((int)(4294967295L | 1));
结果:
4294967295
-1
第二个之所以为 -1 是因为 Java 中整数默认是 int 类型,所以你的 4294967295 | 1 得到的 4294967295 会导致溢出(大于 int 最大范围),溢出后的结果就是 -1
你这个标签有 C/C++/Java,估计是系统自动判断的吧。楼上的解释有些不完全对。在 C/C++ 等语言中,区分有符号和无符号类型,但 Java 中无区分。在 Java 中,表示这样的一个无符号整数,必须用 long,是 64 位的。int 是装不下的,赋值都无法通过编译。但 C/C++ 的话,现在主流 x86 平台的 int 和 long 都是 32 位宽,不会出现无法编译的情况,但可能会警告,而且不管是这个长整数还是 -1,在内存中存储方式都一样。如果是用 C 语言中的 printf 输出,具体的结果和是否有符号无关,取决于格式化字符串如何书写。如果用 C++ 的 count 输出,一般重载了运算符,所以如果变量类型是无符号就输出无符号,变量类型有符号就输出有符号的。C/C++ 的编译器各家的实现和警告信息都略有不同,我这里在 Linux 上的 gcc 编译这段代码,警告如下,但不影响结果。
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
printf("%d\n", 4294967295 | 1);
return 0;
}
cc test.c -o test
test.c: In function ‘main’:
test.c:6:9: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long int’ [-Wformat=]
printf("%d\n", 4294967295 | 1);
^
执行的结果就是输出 -1。
10 回答11.3k 阅读
5 回答4.9k 阅读✓ 已解决
4 回答3.2k 阅读✓ 已解决
8 回答6.4k 阅读
2 回答2.8k 阅读✓ 已解决
3 回答2.1k 阅读✓ 已解决
2 回答3.9k 阅读✓ 已解决
首先,4294967295并不能用java的int型表示,java的int是32位但是你这个数字已经是2的32次幂,但是符号位还要占一个啊,所以java的int表示范围为-2147483648到2147483647,看不到你的代码不知道怎么实现的但是应该是强转了int。
那么强转之后4294967295的二进制确实是32个1没错但是由于第一位为1所以表示负数,计算机中负数的值是除符号位之外按位取反再加一(就是补码咯),所以32个1变成了10000000000000000000000000000001,也就是-1,你再按位和1做或操作当然也是-1了。