Java преобразует отрицательный двоичный файл обратно в целое число

Я пытаюсь преобразовать число с основанием 10 в число с основанием 2 и обратно в основание 10. Это работает только для положительного аргумента_десятичного числа.

argument_binary = Integer.toBinaryString(argument_decimal);
back_converted_argument_decimal = Integer.valueOf(argument_binary, 2);

Если аргумент_десятичного числа отрицательный, я получаю «java.lang.NumberFormatException: для входной строки: «11111111111111111111111111111111»»

РЕДАКТИРОВАТЬ: вот что я делаю:

latitude_binary = Integer.toBinaryString((int)(latitude_decimal * 1000000));   
back_converted_latitude_decimal =  Long.parseLong(latitude_binary, 2) / 1000000.0;

что дает мне плохие результаты, такие как -1,1 при преобразовании вперед и назад в 4293,867296


person krzysiek    schedule 23.12.2012    source источник
comment
Вы имеете в виду основание 2 и основание 10, правильно?   -  person fge    schedule 23.12.2012
comment
верный. Извините за недопонимание...   -  person krzysiek    schedule 23.12.2012
comment
Ваша входная строка состоит из 33 символов, так что это неудивительно; Целые числа Java охватывают только 32 бита. Итак, действительно ли есть проблема?   -  person fge    schedule 23.12.2012
comment
мой аргумент_десятичного числа был -1, я не устанавливал аргумент_бинарного вручную на 33 единицы, если вы это предлагаете...   -  person krzysiek    schedule 23.12.2012
comment
Я понимаю вашу проблему, но есть ли в этом какой-то мотив?   -  person nhahtdh    schedule 23.12.2012
comment
Контекст гораздо сложнее, чтобы описать его здесь на моем ломаном английском ;)... Мне просто нужно...   -  person krzysiek    schedule 23.12.2012


Ответы (2)


Попробуйте пройти через длинный:

String binary = Integer.toBinaryString(-1);
long l = Long.parseLong(binary, 2);
int i = (int) l;

Проверено, работает.

Это работает, потому что -1 представлен как последовательность из 32 битов 1 в системной памяти. При использовании метода toBinaryString он создает строку, используя точное представление. Но 32 бита единицы на самом деле равны 2 ^ 32 - 1. Это слишком много для целого числа (4 байта), потому что целое число начинается с [-2 ^ 31, 2 ^ 31-1]. Это потому, что самый левый бит представляет знак. Итак, чтобы исправить это переполнение, сначала интерпретируйте эту последовательность символов 1 и 0 как Long. Подойдет long, потому что максимальное значение для long равно 2^63-1. Затем преобразуйте long в int. Для этого просто берут младшие 32 бита.


Ошибка в вашем коде заключается в том, что вы не преобразовали Long.parseLong в int. Итак, это должно работать:

lat_bin = Integer.toBinaryString((int)(lat_dec * 1000000));   
lat_dec_conv =  ((int) Long.parseLong(lat_bin, 2)) / 1000000.0;
person Martijn Courteaux    schedule 23.12.2012
comment
А для чисел больше 64 бит BigInteger. - person Confusion; 23.12.2012

person    schedule
comment
@MarlonAbeykoon Первый оператор if проверяет, имеет ли переданное число самый левый бит, равный «1», и если это число отрицательное. Следующим шагом является инвертирование битов и вычисление десятичного представления. Если вас смущает вычисление, вы должны изучить дополнение до двух . Надеюсь, поможет :) - person Ivan D.; 18.12.2016