Два дополнения дают другой ответ на java

#java #binary #bit-manipulation #bitwise-operators #twos-complement

Вопрос:

Извините, если мой вопрос является основным или дублирующим другой вопрос. В любом случае, я пытаюсь выполнить дополнение два, чтобы изменить знак числа и проверить результат на java, но результат отличается от того, что я вычисляю вручную.

Например:
8 в двоичном коде равно 00001000
-8 в двоичном коде после выполнения дополнения 2 должно быть 11111000

но когда я использую Integer.parseInt("11111000",2) вместо -8, я получаю 248.
Я неправильно понимаю концепцию дополнения 2 или в Java есть что-то, чего я не знаю.

Не могли бы вы, пожалуйста, помочь мне?

Комментарии:

1. should be 11111000 — нет, распечатайте его, и вы сами все увидите.

2. Это -8 как байт в двоичном формате, конечно. Для an int добавьте еще 24 1 к началу.

3. Взгляните на BigInteger 😉

Ответ №1:

Если вы посмотрите на javadoc, вы увидите:

Анализирует строковый аргумент как целое число со знаком в радиусе, указанном вторым аргументом. Все символы в строке должны быть цифрами указанного радиуса (в зависимости от того, возвращает ли Character.digit(char, int) неотрицательное значение), за исключением того, что первым символом может быть знак минус ASCII » — » («u002D») для обозначения отрицательного значения или знак плюс ASCII » » («u002B») для обозначения положительного значения. Возвращается результирующее целое значение.

Java Integer.parseInt не принимает строки с 2 дополнениями. Фактически, если вы введете 32-символьную строку, вы получите исключение (крайний левый бит внутренне зарезервирован для знака).

Ответ №2:

Я неправильно понимаю концепцию дополнения 2 или в Java есть что-то, чего я не знаю.

Да, вы упустили то, что Integer.parseInt("ones and zeroes", 2) это не java-ese для: Вот несколько битов, пожалуйста, просто дайте мне значение int, которое является этой точной последовательностью битов.

Это, как говорится в методе, «Проанализируйте это число». дополнение 2-это не то, что средний джо на улице понимает как правильную математику.

Если я возьму микрофон, выйду, напишу 11111000 на листе бумаги и спрошу случайных людей на улице: это в базе 2, какой это номер — и вы ожидаете, что они скажут -8, вы явно сошли с ума.

Чтобы было ясно, Integer.parseInt никогда не даст вам отрицательное число, если только строка, которую вы ему передаете, не начинается со знака минус. Это даст вам положительное число, или произойдет сбой, если число в строке не поместится в положительное пространство int числа.

Хорошо, так как же мне это сделать вместо этого?

Там на самом деле не прямой путь, 2 комплекта является реализацией подробно, что вы можете наблюдать, но которое никогда не позволит вам бесшумно написать (будь то в виде строки или как литерал) положительное число, будь то в битах или десятичном или шестнадцатеричном формате, и, тем не менее, что буквальное устранить отрицательное число.

Поэтому вместо этого мы пытаемся наблюдать за этим. Кастинг будет отлично работать:

 int x = 248;
int y = 0b11111000;

// x and y are the exact same value. `javap -c` to observe:
// they are _Exactly_ identical and it is hence impossible to tell the difference.

System.out.println(x == y); // prints true
byte b = (byte) x;
System.out.println(b); // prints -8
 

понятия, используемые здесь:

  • 0b111000 это просто другой способ написания целочисленных литералов. нет никакой разницы между 0x1 , 1 или 0b1 — это все значение 1. в конце концов, все числа являются битами. Они не хранят, как они были сделаны. 0b используется для записи в базе 2, просто напишите число для базы 10, перед 0 для базы 8 и перед 0x для базы 16: 0x10 == 16 == 0b10000 == 020 . Попробуйте это сделать!
  • Приведение к int в байт приведет к тому, что ваши 32 бита будут удалены, отрежьте «крайние левые» 24 бита, а затем вставьте оставшиеся 8 прямо в байт, и если это означает, что число теперь отрицательное, так тому и быть. Это одна из очень немногих операций в java, которая позволяет предположить, что дополнение 2s влияет на то, что происходит (по сравнению с выбрасыванием чего-либо).