Java отрицательный BigInteger toString - PullRequest
1 голос
/ 28 июня 2011

Кажется, у меня есть проблема с двумя дополнениями в 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

Любые советы?

Ответы [ 5 ]

3 голосов
/ 28 июня 2011

Номер всегда умещается в 64 бита:

Если ваш номер всегда умещается в 64 бита, вы можете поместить его в длинную строку и затем распечатать биты / шестнадцатеричные цифры.может не всегда умещаться в 64 бита:

Если число не не всегда умещается в 64 бита, вам придется решать его «вручную».Чтобы преобразовать число в представление его дополнения до двух, выполните следующие действия:

  • Если число положительное, ничего не делать
  • Если число отрицательное:
    • Преобразовать его вего абсолютное значение
    • Дополняют биты
    • Добавить 1

Для BigInteger преобразование выглядит следующим образом:

if (bi.compareTo(BigInteger.ZERO) < 0)
    bi = bi.abs().not().add(BigInteger.ONE);

Если вы напечатаете его, используя bi.toString(2), вы все равно получите знак знака вместо ведущего 1.Это можно решить, просто добавив .replace('-', '1') к строке.

2 голосов
/ 28 июня 2011

Существует метод BigInteger.toByteArray(), который возвращает представление дополнения до двух BigInteger в виде byte[].Все, что вам нужно, это напечатать этот массив в шестнадцатеричной или двоичной форме:

byte[] bs = bi.toByteArray();
for (byte b: bs) {
     System.out.print(String.format("%02X", 0xff & b));
}
1 голос
/ 28 июня 2011

Если число составляет 64 бита или меньше, то простой способ решить эту проблему - преобразовать в long и затем использовать Long.toHexString().

1 голос
/ 28 июня 2011

Двоичное число 1100000000000000000000000000000000000000000000000000000000000000000000000000, безусловно, является положительным числом, верно.Это равно 2 ^ 63 + 2 ^ 62.Я не понимаю, почему вы ожидаете, что отрицательное число станет положительным при преобразовании в основание 2 или основание 16.

Вы путаете представление base n с внутренним представлением чисел.

0 голосов
/ 28 июня 2011

что ты имеешь ввиду?Вы хотите получить дополнение Two?

, если вы это имеете в виду, может быть, я могу привести вам пример

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);
 }
}  
...