Java 如果位标志的长度为31,加上一个负/正标志,为什么1加31个零不是有效的整数?

Java 如果位标志的长度为31,加上一个负/正标志,为什么1加31个零不是有效的整数?,java,int,bit-manipulation,Java,Int,Bit Manipulation,据介绍,在第一张表格下面的第四段左右说 通常,我们将使用一个整数来表示域上最多32个值或64个值的集合,使用64位整数,1位表示存在的成员,0位表示不存在的成员 如果这是真的,那么为什么这个32位二进制数超过Integer.MAX_值 错误: Exception in thread "main" java.lang.NumberFormatException: For input string: "10000000000000000000000000000000" at java.la

据介绍,在第一张表格下面的第四段左右说

通常,我们将使用一个整数来表示域上最多32个值或64个值的集合,使用64位整数,1位表示存在的成员,0位表示不存在的成员

如果这是真的,那么为什么这个32位二进制数超过Integer.MAX_值

错误:

Exception in thread "main" java.lang.NumberFormatException: For input string: 
"10000000000000000000000000000000"
    at java.lang.NumberFormatException.forInputString(Unknown Source)
    at java.lang.Integer.parseInt(Unknown Source)
    at Test.main(Test.java:10)
Exception in thread "main" java.lang.NumberFormatException: For input string: 
"10000000000000000000000000000000"
    at java.lang.NumberFormatException.forInputString(Unknown Source)
    at java.lang.Integer.parseInt(Unknown Source)
    at Test.main(Test.java:10)
原始答复:

我想出来了。网页为我清理了它:

Java整数是32位的。最高位保留给加号或减号。因此,您可以设置/取消设置31个一位标志

我的误解是,位标志以这种方式使用整数中的第32位作为负数或正数标记,好像它是这样做的一个选项。但是Java用这种方式定义了一个整数,所以它不是一个选项,而是该定义的结果或副产品。整数只有31位表示数字本身。第32位用作加减

写了这篇文章后,我发现甚至说位标志使用任何东西都没有意义。位标志是概念,整数是具体类型

更新:一些意见:

Integer.MIN_值等于-2147483648,二进制形式为

10000000000000000000000000000000
10000000000000000000000000000000
第一位表示负。在这种情况下,它是一个符号位,因为这是一个有符号整数。最小值为负,最小值和最大值与零等距。如果它是一个无符号整数,它将只是另一个值位

:

签字:

int:默认情况下,int数据类型是32位带符号2的补码整数,最小值为-231,最大值为231-1

未签名:

在JavaSE8及更高版本中,可以使用int数据类型表示无符号32位整数,该整数的最小值为0,最大值为232-1。使用Integer类将int数据类型用作无符号整数。有关更多信息,请参阅数字类一节。向Integer类添加了静态方法,如compareUnsigned、divideUnsigned等,以支持无符号整数的算术运算

同样:Integer.MIN_值等于-2147483648,二进制形式为

10000000000000000000000000000000
10000000000000000000000000000000
将该符号位更改为零不会使其成为2147483648 Integer.MAX_值。成功了

00000000000000000000000000000000
这是零。二进制中的Integer.MAX_值为

01111111111111111111111111111111
将符号位切换为1不会使其成为最小值

由于32位对于有符号整数的值部分来说太大,因此尝试分析此项失败:

错误:

Exception in thread "main" java.lang.NumberFormatException: For input string: 
"10000000000000000000000000000000"
    at java.lang.NumberFormatException.forInputString(Unknown Source)
    at java.lang.Integer.parseInt(Unknown Source)
    at Test.main(Test.java:10)
Exception in thread "main" java.lang.NumberFormatException: For input string: 
"10000000000000000000000000000000"
    at java.lang.NumberFormatException.forInputString(Unknown Source)
    at java.lang.Integer.parseInt(Unknown Source)
    at Test.main(Test.java:10)
相当于

11111111111111111111111111111111

符号位表示负。32个1的二进制数字是-1。我一时想不起为什么。我也不知道如何解析负号二进制。这个

Integer.parseInt("-1111111111111111111111111111111", 2)
等于

   num:   -2147483647
          10000000000000000000000000000001
所以它是满溢的还是什么

测试等级:

public class BinaryNumberTest  {
  public static final void main(String[] ignored)  {
     testNum(Integer.parseInt("-1111111111111111111111111111111", 2), "-1111111111111111111111111111111");
     testNum(Integer.MAX_VALUE, "Integer.MAX_VALUE");
     testNum(0, "0");
     testNum(Integer.MIN_VALUE, "Integer.MIN_VALUE");
  }
  private static final void testNum(int num, String description)  {
     System.out.println(description + ": " + num);
     System.out.println();

     int numMinus1 = num - 1;
     System.out.println("   num-1: " + numMinus1);
     System.out.println("          " + get32BitZeroPaddedBinaryNum(numMinus1));

     System.out.println("   num:   " + num);
     System.out.println("          " + get32BitZeroPaddedBinaryNum(num));

     int numPlus1 = num + 1;
     System.out.println("   num+1: " + numPlus1);
     System.out.println("          " + get32BitZeroPaddedBinaryNum(numPlus1));
     System.out.println();
  }

  private static final String get32BitZeroPaddedBinaryNum(int num)  {
     return  String.format("%32s", Integer.toBinaryString(num)).replace(' ', '0');
  }
}
输出:

-1111111111111111111111111111111: -2147483647

   num-1: -2147483648
          10000000000000000000000000000000
   num:   -2147483647
          10000000000000000000000000000001
   num+1: -2147483646
          10000000000000000000000000000010

Integer.MAX_VALUE: 2147483647

   num-1: 2147483646
          01111111111111111111111111111110
   num:   2147483647
          01111111111111111111111111111111
   num+1: -2147483648
          10000000000000000000000000000000

0: 0

   num-1: -1
          11111111111111111111111111111111
   num:   0
          00000000000000000000000000000000
   num+1: 1
          00000000000000000000000000000001

Integer.MIN_VALUE: -2147483648

   num-1: 2147483647
          01111111111111111111111111111111
   num:   -2147483648
          10000000000000000000000000000000
   num+1: -2147483647
          10000000000000000000000000000001

在基数2中,100000000000000000000000即31个零等于2^31。Java int是-2^31和2^31-1之间的数字的32位二补表示;这个范围当然不包括2^31。这就是为什么这个值不能转换成整数的原因——尽管长的也可以

如果您有一个位为100000000000000000000000000000的Java int仍然是31个零,那就是-2^31

Java int的第一位不是正/负标志。它只是一个位值为-2^31的数字。

它超过了Integer.MAX\u值,因为它确实超过了Integer.MAX\u值。它是Integer.MAX_值+1,您可以在int空间中绝对计算它,您可以将其记为0x8000000或Integer.MIN_值,但它将是负数

这就是Parsent抱怨的原因

你不能这样解析它-你完全可以用一个int来表示一个32位的位向量。符号位是一个误导性的名称,但我们似乎被它卡住了,它只是一个普通的位,就像其他任何位一样。其特殊含义仅在以下情况下发挥作用:

转换为字符串/从字符串转换 转换为更宽的或浮点类型 除法与余数 右移,请参见>>vs>>> 除相等外的比较,例如1>0x8000000。您可以比较长x和y,就好像它们是用x^long.MIN_值 加减法 包括左移位的位运算 乘法 平等测试 转换为更窄的类型
如果将int解释为位向量,则符号位将只是一个普通位,但必须注意对其执行的所有操作都同意这一点。

使用Integer.parseInt时,必须明确确定转换值的符号。因此,如果它的Integer.MIN_值,对于parseInt,它如下所示:

Integer.parseInt("-10000000000000000000000000000000", 2);
-仍然是32位,但前缀为负号。如果没有使用标志,则第一个 t位符号位默认为零正值,您将无法转换包含超过31位的值,这就是为什么您选择NumberFormatException-Integer.MAX_值为011111111111111111

也可以使用Integer.parseUnsignedInt:

Integer.parseUnsignedInt("10000000000000000000000000000000", 2);

在这里,二进制值将按原样转换,第一位将被解释为符号位。两种情况下的结果都是-2^31

我很困惑。在标题中,您明确表示您有1+31=32个字符。你知道有一个位用于标志。是什么让你认为你仍然可以创建一个32位的整数?编辑:愚蠢的草率评论。@Jeroenvanevel:我澄清了一下我的答案。你链接的那个网页很容易误导人。最高位绝对不是像它声称的那样为加号或减号保留的。MSB是一个表示-2^31的值位。如果你误导性地引用它一个符号位,你就错误地暗示它没有自己的值。请停止将其称为符号位。Integer.MAX_值为2^^31-1,而您的号码又是一个,2^^31。对于有符号整数,顶部的位表示为负。这就是两个补码的工作原理。