4

Java で負の数を符号なしの値に解析することは可能BigIntegerですか?

たとえば、私は と解釈-1FFFFFFFFFFFFFFFFます。

4

9 に答える 9

11

コンストラクタを使ってみる

public BigInteger(int signum, byte[] magnitude)

正の数を作成することを指定するには、最初のパラメーターを 1 に設定する必要があります。バイト配列は、BIG ENDIAN ORDER で解析している数値です。最初のパラメーターを 1 に設定すると、符号なしの数値として解釈されます。唯一の秘訣は、数値をバイト配列に入れることですが、それほど難しくはありません。

編集:ここで手動のビット演算を行う必要があるようです。私があなたの問題を正しく理解していれば、String を Long として解釈し、その long を unsigned として解釈し、それを BigInteger クラスに格納する必要があります。私はこれをします。

public BigInteger getValue(String numberString)
{
   Long longValue = Long.valueOf(numberString);
   byte [] numberAsArray = new byte[8];  
   for(int i = 0; i < 8; i++)
   {  
      numberAsArray[7 - i] = (byte)((longValue >>> (i * 8)) & 0xFF);
   }
   return new BigInteger(1, numberAsArray);
}  
于 2012-06-04T19:23:56.747 に答える
7

2 の補数を考えている場合は、ワーキング ビット長を指定する必要があります。Java long は 64 ビットですが、BigInteger は制限されません。

あなたはこのように何かをすることができます:

// Two's complement reference: 2^n . 
// In this case, 2^64 (so as to emulate a unsigned long)
private static final BigInteger TWO_COMPL_REF = BigInteger.ONE.shiftLeft(64);

public static BigInteger parseBigIntegerPositive(String num) {
    BigInteger b = new BigInteger(num);
    if (b.compareTo(BigInteger.ZERO) < 0)
        b = b.add(TWO_COMPL_REF);
    return b;
}

public static void main(String[] args) {
    System.out.println(parseBigIntegerPositive("-1").toString(16));
}

しかし、これは、0 から 2^64-1 の範囲で BigInteger を使用していることを暗に意味します。

または、より一般的に:

public static BigInteger parseBigIntegerPositive(String num,int bitlen) {
    BigInteger b = new BigInteger(num);
    if (b.compareTo(BigInteger.ZERO) < 0)
        b = b.add(BigInteger.ONE.shiftLeft(bitlen));
    return b;
}

より安全にするために、いくつかのチェックを追加できます。

public static BigInteger parseBigIntegerPositive(String num, int bitlen) {
    if (bitlen < 1)
        throw new RuntimeException("Bad bit length:" + bitlen);
    BigInteger bref = BigInteger.ONE.shiftLeft(bitlen);
    BigInteger b = new BigInteger(num);
    if (b.compareTo(BigInteger.ZERO) < 0)
        b = b.add(bref);
    if (b.compareTo(bref) >= 0 || b.compareTo(BigInteger.ZERO) < 0 )
        throw new RuntimeException("Out of range: " + num);
    return b;
}
于 2012-06-04T20:20:59.503 に答える
1

2 の補数はいつでも手動で行うことができます。数値が 0 より小さい場合は、すべてのビットを逆にして 1 を追加します。

于 2012-06-04T19:25:55.263 に答える
0

このユーティリティを使用して、符号なし整数に変換できます。BigInteger のサイズは無制限であるため、翻訳で保持する符号拡張の量を決定するには、サイズを指定する必要があります。

public static BigInteger toPositive(BigInteger num, int sizeInBytes) {
    return num.andNot(BigInteger.valueOf(-1).shiftLeft(sizeInBytes * 8));
}
于 2014-03-06T21:24:27.747 に答える