Добрый день!
Есть файлы с базами данных, которые сохраняет старенькое оборудование, работающее на, кажется, Delphi. Файл состоит из шапки и сырых чисел в формате real48 (6-байтовое число с плавающей точкой).
Этот формат нативно не поддерживается python. Все полтора найденных скрипта в интернете по преобразованию real48 to float (1 проект на гитхабе и какой-то код 2001 года на Пайтон 2.х) работают неправильно (выдают неверное число при попытке скормить в них байтовую строку считанную с этих файлов).
Пробовал долбить чатгпт, но большая часть предложенных скриптов был полнейший бред, а те что выглядели осмысленно не выдавали вообще никаких результатов кроме числа 0.0. (Я только после 5 запроса смог убедить бота, что добавлять 2 нулевых байта в конец строки, а затем использовать unpack для float64 - это не выход).
В общем прошу вашей помощи. Может я изначально выбрал неверную стратегию и мне нужно написать и скомпилировать конвертер на Паскале, а затем через subprocess его запускать? Или я не знаю о более очевидных способах решения данной проблемы?
Главная и единственная проблема - преобразование устаревшего real48 в понимаемый питоном float.
ВеткаДобрый день!
19 сообщений · –С Ю Ю F Ю Ю Ссылка
нажмите — покажемhttps://www.cyberforum.ru/csharp-beginners/thread2497619.html посмотри тут, там переводится во флоатT F
B Код Delphi для генерации тестового файла: var r: Real48; begin with TFileStream.Create('d:\rtest.dat', fmCreate) do try r := -8.1234567e-22; Write(r, SizeOf(r)); r := 0.2; Write(r, SizeOf(r)); r := 1.0; Write(r, SizeOf(r)); r := -3.1515926; Write(r, SizeOf(r)); r := 2.71828183e17; Write(r, SizeOf(r)); finally Free; end;B Python: import struct #transforms 6 bytes of array ar starting from id index def real48_double(ar, id): b64 = [0]*8 b64[7] = ar[id+5] & 0x80 #sign ex64 = int(ar[id]) - 129 + 1023 #exponent b64[7] = b64[7] | (ex64 >> 4) b64[6] = (ex64 & 0xF) << 4 #mantissa stuff man5 = ar[id+5] & 0x7f b64[6] = b64[6] | (man5 >> 3) b64[5] = (man5 & 0x7) << 5 b64[5] = b64[5] | (ar[id+4] >> 3) b64[4] = (ar[id+4] & 0x7) << 5 b64[4] = b64[4] | (ar[id+3] >> 3) b64[3] = (ar[id+3] & 0x7) << 5 b64[3] = b64[3] | (ar[id+2] >> 3) b64[2] = (ar[id+1] & 0x7) << 5 b64[2] = b64[2] | (ar[id+1] >> 3) return struct.unpack('d', bytes(b64))[0] with open("d:/rtest.dat", mode="rb") as reals: re = reals.read() for i in range(0, len(re), 6): d = real48_double(re, i) print(d) [Dbg]>>> -8.123456707855156e-22 0.20000000005711627 1.0 -3.1515926018473692 2.718281829323899e+17F K B
A B