按位或取值为负值

4294967295 | 1 //-1 

4294967295 二进制是 11111111111111111111111111111111 32位

1 是 00000000000000000000000000000001

那么按位或的结果应该还是 11111111111111111111111111111111

转化十进制也就是 4294967295

可结果就是 -1

哪位大佬解释下

阅读 4.6k
4 个回答

首先,4294967295并不能用java的int型表示,java的int是32位但是你这个数字已经是2的32次幂,但是符号位还要占一个啊,所以java的int表示范围为-2147483648到2147483647,看不到你的代码不知道怎么实现的但是应该是强转了int。
那么强转之后4294967295的二进制确实是32个1没错但是由于第一位为1所以表示负数,计算机中负数的值是除符号位之外按位取反再加一(就是补码咯),所以32个1变成了10000000000000000000000000000001,也就是-1,你再按位和1做或操作当然也是-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。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题