#java #c_sharp #битовые_операции
Есть строка из 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. Подскажите, в чём соль между этими языками и как решить такую проблему.
Ответы
Ответ 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;
Комментариев нет:
Отправить комментарий