Endian преобразование подписанных целых - PullRequest
3 голосов
/ 05 декабря 2009

Я получаю данные с прямым порядком байтов по UDP и преобразую их в байты с прямым порядком байтов. Источник говорит, что целые числа подписаны, но когда я поменяю местами байты со знаком (особенно 16-битные), я получаю нереальные значения. Когда я обмениваю их как неподписанные целые, я получаю то, что ожидаю. Я полагаю, что исходная документация может быть неправильной и на самом деле отправляет 16-разрядные целые числа без знака. Но почему это имеет значение? Предполагается, что все значения положительны и находятся под 16-битным INT_MAX, поэтому переполнение не должно быть проблемой. Единственное, о чем я могу подумать, это то, что (1) документация неверна И (2) я неправильно обрабатываю знаковый бит при выполнении подписанного свопа с порядком байтов байтов.

У меня действительно есть два вопроса:

1) Если переполнение не является проблемой, имеет ли значение, прочитал ли я целые числа со знаком или без знака.

2) Различаются ли порядки замены порядка байтов между значениями со знаком и без знака (т. Е. Нужно ли по-разному обрабатывать бит знака)?

Я думал, что преобразование в обратный порядок выглядело одинаково для значений со знаком и без знака, например для 16-битных value = value&0xff00 >> 8 | value&0x00ff << 8.

Спасибо

1 Ответ

12 голосов
/ 05 декабря 2009

У вас проблемы с расширением знака в вашей функции подкачки. Вместо этого:

value & 0xff00 >> 8 | value & 0x00ff << 8

сделать это:

((value >> 8) & 0x00ff) | ((value & 0x00ff) << 8)

Проблема в том, что если value является 16-битным значением со знаком, то 0xabcd >> 8 равно 0xffab. Самый старший бит остается равным 1, если он начинается со значения 1 во сдвиге вправо со знаком.

Наконец, вместо написания этой функции самостоятельно, вы должны использовать ntohs().

...