Почему побитовое И двух коротких значений приводит к значению int в Java? - PullRequest
4 голосов
/ 17 февраля 2010
short permissions = 0755;
short requested = 0700;
short result = permissions & requested; 

Я получаю ошибку компилятора:

error possible loss of precision
found   : int
required: short

Если я не совсем ошибаюсь, результат двоичного И будет длиннее самого длинного операнда. Почему результат является целым числом?

Был бы удар по производительности, если бы я бросил на шорт?

(short) permissions & requested

Ответы [ 5 ]

6 голосов
/ 17 февраля 2010

Краткий ответ (хах!): двоичное числовое продвижение .

  • Если какой-либо из операндов имеет ссылочный тип, преобразование без ящика (§5.1.8) выполняется.Затем:
  • Если один из операндов имеет тип double, другой преобразуется в двойной.
  • В противном случае, если один из операндов имеет тип float, другой преобразуется в float.
  • В противном случае, если один из операндов имеет тип long, другой преобразуется в long.
  • В противном случае оба операнда преобразуются в тип int.
3 голосов
/ 17 февраля 2010

Если я не совсем ошибаюсь, результат двоичное И до тех пор, пока самый длинный операнд. Почему результат является целым числом?

Поскольку в спецификации языка Java сказано, что результатом недлинной целочисленной арифметики всегда является int. Вероятно, так было написано в подтверждение того факта, что 32-битные процессоры все равно работают так же, как внутри - у них на самом деле нет способа выполнять арифметику с шортами.

Был бы удар по производительности, если бы я бросил на короткую?

По причине, приведенной выше: нет - это должно произойти в любом случае.

2 голосов
/ 17 февраля 2010

На самом деле, я подозреваю, что вы можете получить удар по производительности. Существуют только Java-байт-коды для побитовых операций со значениями int и long. Таким образом, значения short в переменных permission и requested должны (в теории) быть расширены до того, как будет выполнена операция.

(И кроме того, я думаю, вы обнаружите, что нативные побитовые инструкции доступны только в 32- и 64-битных версиях. Или, если есть 8- или 16-битные версии, они будут использовать то же количество тактов, что и 32-битные версия. Пути к данным ЦП будут иметь ширину не менее 32 бит, и для и / или / xor нет способа заставить более узкие типы работать быстрее.)

Кроме того, хотя три переменные имеют тип short, JVM выделит одинаковое количество байтов для их хранения. Это является следствием того, как спроектирована JVM.

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

2 голосов
/ 17 февраля 2010

Я просто хотел добавить, что вы действительно можете избежать приведения, если используете операторы арифметического присваивания. Это не быстрее и не медленнее, просто что-то, что было бы приятно узнать.

short permissions = 0755;
short requested = 0700;
short result = permissions;
result &= requested;
1 голос
/ 17 февраля 2010

Операнды к оператору & будут преобразованы в int, и, следовательно, результатом будет int, который должен быть приведен к короткому, если вы хотите сохранить его в result. Я не думаю, что это должно быть снижение производительности, если компилятор не плохо генерирует код.

С http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.22.1:

Когда оба операнда оператора &, ^ или | имеют тип, который может быть преобразован (§5.1.8) в примитивный целочисленный тип, двоичное числовое продвижение сначала выполняется над операндами (§5.6.2).

С http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#170983:

[...] В противном случае оба операнда преобразуются в тип int.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...