Java На AND - короткое с коротким, оно обновляется до int и возвращает странные значения

Я создаю маску и устанавливаю старшие биты в коротком как это:

  enum FLAGS {FLAG1, FLAG2, FLAG3, FLAG4, FLAG5, FLAG6};

  public static void setFlag(short len, FLAGS flag) {
       short mask = 1 << (Short.SIZE - flag.ordinal() - 1);
       len |= mask;
  }

Я напечатал значения:

  len: 0000001111111100
  mask : 1000000000000000
  after OR'ing with mask: 11111111111111111000001111111100

Я понимаю, что когда мы выполняем битовые манипуляции с шортами, они преобразуются в int, чтобы избежать переполнения, но почему тогда устанавливаются все старшие биты? Как я могу просто установить любой из первых 6 битов без какого-либо забавного кастинга?

4 ответа

short подписан, и ваша маска отрицательна. Это сохраняется, когда оно расширяется int, Вы можете сделать старшие биты нулевыми, маскируя маску:

len |= (mask & 0xffff);

Теперь, если бы len был int или же long, но поскольку оно короткое, у него все равно не будет этих старших бит. Так что действительно расширение происходит в какой-то другой части вашего кода.

Похоже, что вы или не и. '|' это или, "&" это и. Кроме того, вы делаете короткую и короткую ставку, а не короткую и короткую. Ваше печатное заявление даже говорит "И", тогда как в заголовке "И". Если вы используете '&=', я думаю, что это решит вашу проблему.

Когда short превращается в int, его числовое значение сохраняется. Если старший бит равен 1, short является отрицательным числом, и чтобы сохранить его значение, int должен быть отрицательным - то есть, самый высокий бит int должно быть также 1, и все биты между ними.

В общем, при конвертации short для intотрицательные числа дополняются слева до 1, а положительные - слева от 0.

Просто приведите результат к короткому. Вы получаете расширение знака в int результат, потому что немного 0x8000 устанавливается в маске, которая является знаковым битом.

когда мы выполняем битовые манипуляции с шортами, они преобразуются в int, чтобы избежать переполнения,

Нет, переполнение невозможно, поэтому это не может быть причиной. Причина заключается в согласованности с другими операциями, которые могут переполниться, например, +,-,*,/.

Другие вопросы по тегам