Чтение IBM с плавающей запятой в C++

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

Я открыл файл и прочитал заголовки следующим образом:

ifs.open(fileName, std::ifstream::in | std::ifstream::binary);
char textHeader[3200];
BinaryHeader binaryHeader;
ifs.read(textHeader,sizeof(textHeader));
ifs.read(reinterpret_cast<char *>(&binaryHeader), sizeof(binaryHeader));

В документации говорится, что данные хранятся как: 4-байтовые IBM с плавающей запятой, и я пробовал что-то подобное:

vector<float> readData(int sampleSize){
    float tmp;
    std::vector<float> tmpVector;
    for (int i = 0; i<sampleSize; i++){
        ifs.read(reinterpret_cast<char *>(&tmp), sizeof(tmp));
        std::cout << tmp << std::endl;
        tmpVector.push_back(tmp);
    }
    return tmpVector;
}

К сожалению, результат не кажется правильным. Что я делаю неправильно?

РЕДАКТИРОВАТЬ: Забыл упомянуть, что двоичные данные имеют обратный порядок байтов, но если я распечатаю значения tmp, данные в любом случае не кажутся правильными.

Вывод: 4-байтовое число IBM с плавающей запятой — это не то же самое, что число с плавающей запятой.


person timko.mate    schedule 17.02.2019    source источник
comment
Трудно сказать точно, но на первый взгляд я вижу две проблемы. Сначала у вас есть массив символов для вашего заголовка, это может быть хорошо, но вы пытались вместо этого использовать беззнаковый символ? Вторая возможная проблема заключается в том, что в вашей функции readData() вы создаете временный вектор в этом кадре стека функций, а затем возвращаете его. Возможно, попробуйте изменить сигнатуру этой функции, чтобы принять std::vector<float> по ссылке и передать ее в функцию, а не возвращать копию во временную.   -  person Francis Cugler    schedule 18.02.2019
comment
Двоичные данные большие или маленькие?   -  person Retired Ninja    schedule 18.02.2019
comment
@RetiredNinja Это хороший вопрос к ОП, это тоже будет иметь огромное значение!   -  person Francis Cugler    schedule 18.02.2019
comment
Да спасибо. Забыл упомянуть все значения в заголовке с обратным порядком байтов.   -  person timko.mate    schedule 18.02.2019
comment
stackoverflow .com/questions/2782725/   -  person Retired Ninja    schedule 18.02.2019
comment
«4-байтовое число с плавающей запятой IBM», вероятно, не то же самое, что float. Если это так, вам придется проделать некоторую работу, чтобы преобразовать ввод во что-то, с чем может работать ваше оборудование.   -  person Pete Becker    schedule 18.02.2019
comment
Да, именно этого я и боялся. Спасибо!   -  person timko.mate    schedule 18.02.2019
comment
Это может быть формат: nssdc.gsfc.nasa.gov/nssdc/ formats/IBM_32-Bit.html en.wikipedia.org/wiki/IBM_hexadecimal_floating_point   -  person Retired Ninja    schedule 18.02.2019
comment
Погуглите «4-байтовые числа IBM с плавающей запятой». Там много информации. И, как я уже догадался, это не то же самое, что IEEE float.   -  person Pete Becker    schedule 18.02.2019
comment
Можете ли вы опубликовать один пример вывода std::cout << std::hex << (int&)(tmp) << std::endl;   -  person rustyx    schedule 18.02.2019
comment
Да, я получил это: 33331341 3d331341 48331341 52331341 5d331341 67331341 72331341 7c331341 87331341 91331341 9c331341 a6331341 b1331341 bb331341 c6331341 d0331341 db331341 e5331341 f0331341 fa331341 4341341 f341341 19341341 24341341 2e341341 39341341 43341341 4e341341 58341341 63341341 6d341341 78341341 82341341 8d341341 97341341 a2341341 ac341341 b7341341 c1341341 cc341341 d6341341 e1341341 eb341341 f6341341   -  person timko.mate    schedule 18.02.2019


Ответы (1)


person    schedule
comment
Спасибо! Я думаю, что самая большая проблема, как упомянул Пит Беккер, заключается в том, что число с плавающей запятой и 4-байтовое число с плавающей запятой IBM не одно и то же. Данные в обратном порядке. У меня есть функция, которая преобразует их в прямой порядок байтов, но результат в любом случае неверен. - person timko.mate; 18.02.2019
comment
Нет ничего плохого в возврате вектора по значению. И проблема не возникает при чтении заголовка, так что сделать его неподписанным не поможет. - person Pete Becker; 18.02.2019
comment
@PeteBecker Да, я не был уверен на 100%, но упомянул об этом на всякий случай. Тем не менее, я все еще думаю, что возврат вектора локальным временным файлом - это просто неблагоприятный дизайн кодирования, с большими контейнерами, которые заполняются данными или манипулируют их содержимым, я предпочитаю передавать их функциям по ссылке. Однако самой большой проблемой, на мой взгляд, является фактическое представление данных в самой памяти. - person Francis Cugler; 18.02.2019
comment
Что ж, это может быть разумным советом по стилю, но он не решит проблему. - person Pete Becker; 18.02.2019
comment
@PeteBecker Я переформулировал свой ответ, чтобы больше об этом подумать. - person Francis Cugler; 18.02.2019