Русский
Открыть в Telegram

ВеткаДобрый день!

19 сообщений · –
F
Добрый день! Есть файлы с базами данных, которые сохраняет старенькое оборудование, работающее на, кажется, Delphi. Файл состоит из шапки и сырых чисел в формате real48 (6-байтовое число с плавающей точкой). Этот формат нативно не поддерживается python. Все полтора найденных скрипта в интернете по преобразованию real48 to float (1 проект на гитхабе и какой-то код 2001 года на Пайтон 2.х) работают неправильно (выдают неверное число при попытке скормить в них байтовую строку считанную с этих файлов). Пробовал долбить чатгпт, но большая часть предложенных скриптов был полнейший бред, а те что выглядели осмысленно не выдавали вообще никаких результатов кроме числа 0.0. (Я только после 5 запроса смог убедить бота, что добавлять 2 нулевых байта в конец строки, а затем использовать unpack для float64 - это не выход). В общем прошу вашей помощи. Может я изначально выбрал неверную стратегию и мне нужно написать и скомпилировать конвертер на Паскале, а затем через subprocess его запускать? Или я не знаю о более очевидных способах решения данной проблемы? Главная и единственная проблема - преобразование устаревшего real48 в понимаемый питоном float.
  1. Ю
    Поищи описание преобразования в паскале, чтобы понять, что за формат данных. Никто свой формат для базы данных не придумывает, типы данных стандартные. Возможно не то ищешь.
    1. F
      Формат real48 активно использовался очень давно, и так же давно устарел. В инете есть его структура на английской вики, но я пока не до конца разобрался в ней.
        1. F
          Спасибо, тут я уже был:) вроде разобрался+-, попробую еще потыкать
          1. K
            Feanor IV, Вы увеличили карму Юрий Алексеев до 57.07 (+7.07)
          2. Ю
            Понять главное, алгоритм преобразования. Питон работает и с двоичными и с шеснадцатиричными данными. В одном потоке, но достаточно быстро.
      1. T
        Если он активно использовался давно, то скорее всего есть преобразователи на Си в 8 байтовый double
        1. F
          Вероятно должны быть, но я не нашёл=(
  2. 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;
  3. 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+17
    1. F
      Спасибо! Это отлично работает, проверил на реальных данный, всё сходится!
      1. K
        Feanor IV, Вы увеличили карму Boris N (MBo) до 58.41 (+8.41)
ССообщество Python ПрограммистовСообщество Python Программистов@python_scripts · группа · Технологии
4 169участников43пишущих за 30 дней
Лента площадки Открыть в Telegram

Открытая публичная лента из поискового индекса ChatCrawler — «Google по публичному Telegram»; обновляется по мере обхода площадки. Время — UTC.

Только публичный контент, официальный API Telegram. О проекте · Вопросы · Границы индекса · Убрать страницу из выдачи · Каталог · Поиск · Как мы считаем