Почему замена байтов с плавающей запятой отличается от замены целочисленных байтов? - PullRequest
3 голосов
/ 28 апреля 2010

У меня есть двоичный файл двойников, который мне нужно загрузить с помощью C ++. Однако моя проблема заключается в том, что он был написан в формате с прямым порядком байтов, но оператор fstream >> будет считывать число неправильно, потому что моя машина имеет младший порядок. Это кажется простой проблемой для целых чисел, но для двойных и плавающих чисел решения, которые я нашел, не будут работать. Как я могу (или я должен) это исправить?

Я прочитал это как ссылку для замены целочисленных байтов:
Как преобразовать значения с прямым и младшим порядком байтов в C ++?

РЕДАКТИРОВАТЬ: Хотя эти ответы являются поучительными, я обнаружил, что моя проблема с самим файлом, а не формат двоичных данных. Я полагаю, что мой обмен байтов работает, я просто получаю запутанные результаты. Спасибо за вашу помощь!

Ответы [ 2 ]

6 голосов
/ 28 апреля 2010

Самый переносимый способ - это сериализация в текстовом формате, чтобы у вас не было проблем с порядком байтов. Вот как работает operator>>, поэтому у вас не должно быть проблем с порядком байтов при >>. Основная проблема с двоичными форматами (которая объясняет проблемы с порядком байтов) состоит в том, что числа с плавающей запятой состоят из числа битов мантиссы, числа экспонентных битов и знакового бита. Экспонента может использовать смещение. Это означает, что прямой порядок байтов может быть недостаточным в зависимости от исходного и целевого формата.

Если вы используете IEEE-754 на обеих машинах, то вы можете быть в порядке с прямым обращением байтов, так как этот стандарт определяет формат обмена битовыми строками, который должен быть переносимым (за исключением проблем порядка байтов).

Если вам нужно выполнить преобразование между двумя архитектурами компьютеров и использовать дамп памяти необработанных байтов, тогда, пока базовый числовой формат одинаков (т.е. они имеют одинаковое число битов в каждой части числа), Вы можете прочитать данные в массив unsigned char, использовать некоторые базовые процедуры замены байтов и битов, чтобы исправить формат хранения, а затем скопировать необработанные байты в переменную соответствующего типа.

0 голосов
/ 28 апреля 2010

Стандартные операторы преобразования не работают с двоичными данными, поэтому неясно, как вы попали туда, где находитесь.

Однако, поскольку перестановка байтов работает с байтами, а не с числами, вы выполняете это для данных, предназначенных быть плавающими, как данные, которые будут целыми числами.

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

int32_t raw_bytes;
stream >> raw_bytes; // not an int, just 32 bits of bytes
my_byte_swap( raw_bytes ); // swap 'em
float f = * reinterpret_cast< float * >( & raw_bytes ); // read them into FPU
...