Java で負の数を符号なしの値に解析することは可能BigInteger
ですか?
たとえば、私は と解釈-1
しFFFFFFFFFFFFFFFF
ます。
Java で負の数を符号なしの値に解析することは可能BigInteger
ですか?
たとえば、私は と解釈-1
しFFFFFFFFFFFFFFFF
ます。
コンストラクタを使ってみる
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);
}
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;
}
2 の補数はいつでも手動で行うことができます。数値が 0 より小さい場合は、すべてのビットを逆にして 1 を追加します。
このユーティリティを使用して、符号なし整数に変換できます。BigInteger のサイズは無制限であるため、翻訳で保持する符号拡張の量を決定するには、サイズを指定する必要があります。
public static BigInteger toPositive(BigInteger num, int sizeInBytes) {
return num.andNot(BigInteger.valueOf(-1).shiftLeft(sizeInBytes * 8));
}