似乎我对Java的BigInteger有两个补码问题。 我有一个64位整数,其中只有msb和第二个msb设置为1,其余为0。
在十进制中,这取决于:-4611686018427387904
我的应用程序的Java端将此十进制数字作为字符串接收,并将其转换为BigInteger,如下所示:
BigInteger bi = new BigInteger("-4611686018427387904", 10);
然后,它需要以二进制和十六进制形式显示此数字。 我试着用:
String bin = bi.toString(2);
String hex = bi.toString(16);
但我得到了:
-100000000000000000000000000000000000000000000000000000000000000
-4000000000000000
虽然我希望得到:
1100000000000000000000000000000000000000000000000000000000000000
c000000000000000
任何提示?
答案 0 :(得分:3)
如果你的数字总是适合64位,你可以把它放在一个长的,然后打印位/十六进制数字。
long l = bi.longValue();
String bin = Long.toBinaryString(l);
String hex = Long.toHexString(l);
System.out.println(bin);
System.out.println(hex);
如果数字不总是适合64位,则必须“手动”解决。要将数字转换为它的二进制补码表示,请执行以下操作:
对于BigInteger
转化,如下所示:
if (bi.compareTo(BigInteger.ZERO) < 0)
bi = bi.abs().not().add(BigInteger.ONE);
如果您使用bi.toString(2)
进行打印,则仍会获得签名字符,而不是前导1
。只需将.replace('-', '1')
附加到字符串即可解决此问题。
答案 1 :(得分:2)
有BigInteger.toByteArray()
方法,它将BigInteger
的两个补码表示形式返回为byte[]
。您只需要以十六进制或二进制形式打印该数组:
byte[] bs = bi.toByteArray();
for (byte b: bs) {
System.out.print(String.format("%02X", 0xff & b));
}
答案 2 :(得分:1)
二进制数1100000000000000000000000000000000000000000000000000000000000000肯定是正数,对。它等于2 ^ 63 + 2 ^ 62。 我不明白为什么当你转换为基数2或基数16时,你期望负数变为正数。
您将基本n表示与数字的内部表示混淆。
答案 3 :(得分:1)
如果数字是64位或更少,那么解决此问题的简单方法是转换为long
,然后使用Long.toHexString()
。
答案 4 :(得分:0)
如果你的意思是,也许我可以给你一个例子
import java.util.*;
public class TestBina{
static void printBinaryInt(int i){
System.out.println("int:"+i+",binary:");
System.out.print(" ");
for(int j=31;j>=0;j--)
if(((1<<j)&i)!=0)
System.out.print("1");
else
System.out.print("0");
System.out.println();
}
public static void main(String [] args){
Random rand = new Random();
int i = rand.nextInt();
int j = rand.nextInt();
printBinaryInt(i);
printBinaryInt(j);
printBinaryInt(10);
printBinaryInt(-10);
}
}