конвертировать 32-разрядное целое число со знаком с прямым порядком байтов в целое число со знаком с прямым порядком байтов - PullRequest
0 голосов
/ 10 мая 2018

У меня было несколько беззнаковых 32-разрядных целых чисел с прямым порядком байтов, которые мне нужно было преобразовать, и это было тривиально легко, когда я нашел правильный заголовок:

#include <endian.h>
...
be32toh(some_int);

Однако, endian.h указывает, что это для целых чисел без знака. Для целого числа со знаком я не совсем уверен, что делать, так как не похоже, что существуют заголовочные файлы для такого рода вещей, и я не очень знаком с манипулированием битами в C ++.

Редактировать: Так как формат моего целого числа не совсем понятен, позвольте мне объяснить подробнее. У меня есть целое число в форме

abcdefghijklmnopqrstuvwxyz012345

где каждый символ представляет бит. бит a представляет знак. Я знаю, что байты всегда с прямым порядком байтов, поэтому помимо перемещения байтов в другой порядок, например

yz012345qrstwx...

Мне также нужен какой-то способ убедиться, что бит y показывает знак, а не какой-то бит в числе. Я ... понятия не имею, как это сделать.

Редактировать: моя проблема заключалась в том, что я думал, что знаковый бит всегда был первым в порядке, когда это не так. Знаковый бит всегда является MSB, что означает, что если вы находитесь в форме с прямым порядком байтов, то знаковый бит будет в середине байтов, составляющих ваше целое число.

Ответы [ 2 ]

0 голосов
/ 10 мая 2018

Это имеет смысл только в том случае, если в нативной системе используется порядок байтов с прямым порядком байтов, потому что какой смысл преобразовывать данные в подписи с прямым порядком байтов в системе с прямым порядком байтов?

Так, в системе с прямым порядком байтоввсе, что вам нужно сделать, это привести целое число с прямым порядком байтов к unsigned, преобразовать его, используя be32toh, а затем привести результат к целому числу со знаком.На самом деле, лучше представить бинарный порядок как неподписанный с самого начала, потому что его знак не имеет смысла в системе с прямым порядком байтов.Итак, просто преобразуйте биты без знака, а затем приведите к знаку.

0 голосов
/ 10 мая 2018

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

Скорее всего, у вас может быть последовательность из 4 байтов, представляющая 32-разрядное целое число со знаком, но для преобразования необходимо перевернуть байтымежду различными порядковыми номерами процессора.Чтобы сделать это, вы можете просто обработать количества, как если бы они были без знака, и позволить be32toh() сделать работу за вас:

(int)be32toh((unsigned)some_int);

или, немного более безопасно:

(int32_t)be32toh((uint32_t)some_int);

Это работает, потому что операции приведения при применении к целым числам с одинаковой битовой глубиной фактически оставляют представления в памяти неизменными.Это игнорирует значение знака (и любые тонкости, связанные с представлением целых чисел со знаком, дополняющим два, при выполнении обращения байтов).Я не уверен, что такое поведение гарантировано стандартом C (возможно, вопрос для языковых юристов), но это, вероятно, очень распространенное поведение.Описание на www.cplusplus.com указывает, что, если ваша система использует представление с двойным дополнением для своих целых чисел со знаком (что очень часто встречается), тогда преобразование со знаком в без знака в (uint32_t)some_int сделает все правильновещь.Однако точная интерпретация преобразования со знаком в беззнаковое в (int32_t)be32toh(...) строго зависит от реализации.Итак, опять же, я думаю, что вопрос о том, что будет означать обращение байтов целого числа со знаком , не является математически однозначным.

...