Signed Int32 из двух байт

217
08 февраля 2018, 14:12

Есть строка из Java приложения, которая формирует signed INT из двух байт массива:

final int size = array[0] & 0x00FF | array[1] << 8;

где, array[0] равно 0x08, array[1] равно 0xEE. Этот код формирует число -4600.

Но C# формирует совсем иное число из аналогичного кода:

int size = array[0] & 0x00FF | array[1] << 8;

Но этот код формирует число 60936.

Подскажите, в чём соль между этими языками и как решить такую проблему.

Answer 1

В этой строке

final int size = array[0] & 0x00FF | array[1] << 8;

значение выражения записывается в int (4 байта). Это значит, что все операнды преобразовываются в четырехбайтовые значения.

Расширение разрядности в Java происходит путем копирования старшего бита в исходном числе на расширяемые биты.

Итого у Вас было

final int size = 0x08 & 0x00FF | 0xEE << 8;

или в двоичном виде

final int size = 0000_1000b & 0000_0000_0000_0000_0000_0000_1111_1111b | 1110_1110b << 8;

теперь, что получается при расширении

final int size =
  0000_0000_0000_0000_0000_0000_0000_1000b & 
  0000_0000_0000_0000_0000_0000_1111_1111b | 
  1111_1111_1111_1111_1111_1111_1110_1110b << 8;

В c# такого копирования старшего бита не происходит. (скорее всего там приводится к типу не операнды, а итоговый результат)

Если Вы хотите на Java избежать такого расширения, то применяйте к каждой байтовой переменной операцию побитового И с 0xFF

final int size = array[0] & 0xFF | (array[1] & 0xFF) << 8;

тогда при расширении получится

final int size =
  0000_0000_0000_0000_0000_0000_0000_1000b & 
  0000_0000_0000_0000_0000_0000_1111_1111b | 
  (
    1111_1111_1111_1111_1111_1111_1110_1110b &
    0000_0000_0000_0000_0000_0000_1111_1111b 
  ) << 8;
final int size =
  0000_0000_0000_0000_0000_0000_0000_1000b | 
  0000_0000_0000_0000_0000_0000_1110_1110b << 8;
READ ALSO
Преобразование из long [требует правки]

Преобразование из long [требует правки]

Возникла ошибка в программе, прошу разобратьсяВот скриншоты ошибки и ее места в коде:

217
Как запустить Unirest на с#

Как запустить Unirest на с#

Пытаюсь подключить либу Unirest я понимаю что здесь все написано http://unirestio/net но не могу понять что надо вписать и как создать MyClass

340
Отчет по сети AdMob [Unity][Google play console]

Отчет по сети AdMob [Unity][Google play console]

Подскажите пожалуйста, почему (на скрине) запросов сети намного больше чем сопоставимых? С чем это может быть связано? Реклама показывается...

233
Как получить UserManager

Как получить UserManager

В Веб-Приложении значение UserManager получается через конструктор (не знаю, если честно, как он туда попадает)

231