12

コードのこの部分が失敗するのはなぜですか。

Integer.parseInt("11000000000000000000000000000000",2);

Exception in thread "main" java.lang.NumberFormatException: For input string: "11000000000000000000000000000000"

私が理解している限り、整数は32ビット値です。上のコードの0と1の数は32です。31がある場合、コードは機能します。どうしてこんなことに?

4

4 に答える 4

17

符号付き整数として格納するのに 33 ビットが必要な数値を解析しようとするため、コードは失敗します。

A signed int is a 32 bit value in two's complement representation, where the first bit will indicate the sign of the number, and the remaining 31 bits the value of the number. (-ish.) Java only supports signed integers, and parseInt() and friends aren't supposed to parse two's complement bit patterns – and thus interpret the 1 or (possibly implied) 0 at the 32nd position from the right as the sign. They're meant to support parsing a human-readable reprentation, which is an optional - (or +) for the sign, followed by the absolute value of a number.

このコンテキストでは、説明した動作を期待するのは誤った直感です。基数 2 以外の基数 (または、他の一般的に使用される 2 のべき乗基数) を解析している場合、次の最初の桁を期待しますか?サインに影響を与える入力?明らかにそうではないでしょう。たとえば、意図的にparseInt("2147483648")リターン-2147483648 することは、PHP レベルの狂気です。

特殊ケースの 2 のべき乗ベースも奇妙に感じます。この回答のように、ビットパターンを処理するための別のアプローチを用意することをお勧めします。

于 2012-01-17T02:28:56.483 に答える
4

docsによると、整数の最大値は です2^31-1。これは、バイナリでは次のとおりです。

1111111111111111111111111111111

つまり、311の連続です。

于 2012-01-17T02:31:17.870 に答える
2

これは、Integer.parseInt の場合、"1100000000000000000000000000000" は -1073741824 の 2 の補数表現ではなく、正の値 3221225472 であり、int 値の範囲 -2147483648 から 2147483647 に収まらないためです。

int i = new BigInteger("11000000000000000000000000000000", 2).intValue()

これにより、予想される -1073741824 の結果が得られます

于 2013-08-29T10:54:47.723 に答える
0

あなたの文字列「11.....lots of zeros」は負の整数の正当なバイナリ表現ですが、 Integer.parseInt() は失敗します。これはバグだと思います。

この投稿を読み直すとあまりにも衒学的に聞こえるので、少し気の利いたことを追加します。これがバグであるかどうかに関係なく、Oracleはおそらくあまり気にしないことを理解しています。:-)

あなたが試すことができます:

   long avoidOverflows = Long.parseLong("11000000000000000000000000000000",2);
   int thisShouldBeANegativeNumber = (int)avoidOverflows);
   System.out.println(avoidOverflows + " -> " + thisShouldBeANegativeNumber);


3221225472 -> -1073741824が表示されます。

テキストとしての保存方法によっては、色でこれを行う必要がある場合があります。

ところで、16 進数表現を解析していて、「88888888」のような負の数を解析している場合、正確なことが起こる可能性があります。Long.parseLong() を使用してから変換する必要があります。

于 2012-01-17T02:51:12.353 に答える