Функции для конвертации вещественных чисел (float) в буфер двоичных данных и обратно (IEEE-754) в 1С 8

25.08.23

Разработка - Математика и алгоритмы

В статье рассматривается пример кода на 1С 8.3 для работы с вещественными числами в двоичном формате с использованием стандарта IEEE 754. Статья содержит две основные функции: одна для записи вещественного числа в двоичный буфер, и другая для чтения числа из этого буфера. Код полезен для разработчиков, сталкивающихся с задачами, где необходима конвертация и хранение вещественных чисел, например, в сетевых протоколах или при работе с файлами в определенных форматах.

Появилась необходимость для работы с бинарными файлами читать и писать вещественные числа (float).

1С умеет работать только с целыми числами (функции ЗаписатьЦелое32() и ПрочитатьЦелое32() например), а как быть если необходимо записать и прочитать вещественное число?

Ничего похожего на просторах не нашел, благо начиная с 8.3.11 в 1С появились побитовые операции, написал пару соответствующих функций, выкладываю с комментариями в коде – думаю, кому-нибудь пригодятся либо сами функции, либо как пример использования побитовых операций:
 

// Процедура для тестирования функций записи и чтения чисел
Процедура Тест()
	// Записываем число 123.456 в буфер
	Буфер = ЗаписатьЧислоВБуфер(123.456);
	// Читаем число из буфера и сохраняем в переменную Результат
	Результат = ПрочитатьЧислоИзБуфера(Буфер);
КонецПроцедуры

// Функция для записи вещественного числа в буфер
Функция ЗаписатьЧислоВБуфер(ВещественноеЧисло)
	// Создаем новый буфер размером 4 байта
	Буфер = Новый БуферДвоичныхДанных(4);
	
	// Определяем знак числа
	Знак = ?(ВещественноеЧисло < 0, 1, 0);

	// Обработка случая нулевого числа
	Если ВещественноеЧисло = 0 Тогда
		Буфер.Установить(0, 0);
		Буфер.Установить(1, 0);
		Буфер.Установить(2, 0);
		Буфер.Установить(3, 0);
		Возврат Буфер;
	КонецЕсли;

	// Получаем абсолютное значение числа
	ВещественноеЧисло = Макс(-ВещественноеЧисло, ВещественноеЧисло);

	// Вычисляем экспоненту и мантиссу числа по стандарту IEEE 754
	Экспонента = Цел(Log(ВещественноеЧисло) / Log(2)) + 127;
	Мантисса = Окр((ВещественноеЧисло / POW(2, Экспонента - 127) - 1) * ЧислоИзШестнадцатеричнойСтроки("0x800000"), 0);

	// Формируем 32-битное представление числа
	ЦелоеЧисло = ПобитовыйСдвигВлево(Знак, 31) + ПобитовыйСдвигВлево(Экспонента, 23) + Цел(Мантисса);

	// Записываем байты в буфер
	Буфер.Установить(0, ПобитовоеИ(ЦелоеЧисло, ЧислоИзШестнадцатеричнойСтроки("0xFF")));
	Буфер.Установить(1, ПобитовоеИ(ПобитовыйСдвигВправо(ЦелоеЧисло, 8), ЧислоИзШестнадцатеричнойСтроки("0xFF")));
	Буфер.Установить(2, ПобитовоеИ(ПобитовыйСдвигВправо(ЦелоеЧисло, 16), ЧислоИзШестнадцатеричнойСтроки("0xFF")));
	Буфер.Установить(3, ПобитовоеИ(ПобитовыйСдвигВправо(ЦелоеЧисло, 24), ЧислоИзШестнадцатеричнойСтроки("0xFF")));

	Возврат Буфер;
КонецФункции

// Функция для чтения вещественного числа из буфера
Функция ПрочитатьЧислоИзБуфера(Буфер)
	// Читаем байты из буфера
	Байт1 = Буфер[0];
	Байт2 = Буфер[1];
	Байт3 = Буфер[2];
	Байт4 = Буфер[3];

	// Формируем 32-битное целое число из байтов
	ЦелоеЧисло = Байт1 + ПобитовыйСдвигВлево(Байт2, 8) + ПобитовыйСдвигВлево(Байт3 ,16) + ПобитовыйСдвигВлево(Байт4, 24);

	// Извлекаем знак, экспоненту и мантиссу из 32-битного числа
	Знак = ?(ПобитовыйСдвигВправо(ЦелоеЧисло, 31) >= 1, -1 , 1);
	Экспонента = ПобитовоеИ(ПобитовыйСдвигВправо(ЦелоеЧисло, 23), ЧислоИзШестнадцатеричнойСтроки("0xFF"));
	Мантисса = ПобитовоеИ(ЦелоеЧисло, ЧислоИзШестнадцатеричнойСтроки("0x7FFFFF"));
	
	// Обработка случая нулевого числа
	Если Экспонента = 0 И Мантисса = 0 Тогда
		Возврат 0;
	КонецЕсли;
	
	// Восстанавливаем вещественное число из его экспоненты и мантиссы
	ВещественноеЧисло = (1 + Мантисса / ЧислоИзШестнадцатеричнойСтроки("0x800000")) * POW(2, (Экспонента - 127));

	Возврат ВещественноеЧисло;
КонецФункции

 

FLOAT вещественные числа IEEE-754 побитовые операции

См. также

Универсальные функции Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Благодаря этим пяти строчкам можно больше не заморачиваться с загрузкой из внешних файлов. Пользуюсь везде, всегда и постоянно.

21.05.2024    21031    dimanich70    81    

145

WEB-интеграция Универсальные функции Механизмы платформы 1С Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    15087    YA_418728146    7    

169

Пакетная печать Печатные формы Адаптация типовых решений Универсальные функции Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Абонемент ($m)

Расширение для программ 1С:Управление торговлей, 1С:Комплексная автоматизация, 1С:ERP, которое позволяет распечатывать печатные формы для непроведенных документов. Можно настроить, каким пользователям, какие конкретные формы документов разрешено печатать без проведения документа.

2 стартмани

22.08.2023    3668    57    progmaster    8    

4

Инструментарий разработчика Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 1С:Розница 2 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x Абонемент ($m)

Копирует в буфер значения из списков, из ячеек отчетов, таблиц, настроек списков, других отборов и вставляет в выбранную настройку отбора. Работает с Объект не найден. Работает как в одной так и между разными базами 1С. Использует комбинации [Alt+C] Копировать список, [Alt+V] Вставить список. Также для копирования данных используется стандартная [Ctrl+C] (например из открытого xls, mxl, doc и т.п. файла скопировать список наименований)

1 стартмани

13.10.2022    18613    172    sapervodichka    112    

135

Универсальные функции Механизмы типовых конфигураций БСП (Библиотека стандартных подсистем) Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

В данном материале рассмотрим типовой алгоритм подсистемы контроля учета БСП в конфигурациях на примерах.

18.07.2022    8437    quazare    8    

111

СКД Универсальные функции Программист Стажер Платформа 1С v8.3 Система компоновки данных Конфигурации 1cv8 Бесплатно (free)

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

28.05.2022    10520    milkers    11    

98

Универсальные функции БСП (Библиотека стандартных подсистем) Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

В данной статье я рассматриваю несколько полезных "классических" функций и процедур для работы с данными, которые уже встроены в БСП и готовы к использованию.

25.04.2022    19440    quazare    11    

139
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. qwinter 683 27.08.23 15:39 Сейчас в теме
Чем функция "Формат()" то не угодила? Что вы такого писали, что точности не хватило?
2. a.kuznetsov 109 28.08.23 11:43 Сейчас в теме
(1) Дело не в точности, а в отсутствии возможности декодировать записанное в формате IEEE-754 в файл вещественное число. Т.е. прочитать то можно, но это будет набор из 4 байт, а Вам к примеру, нужно это число декодировать, изменить, закодировать обратно и записать в файл.
3. Evil Beaver 8248 01.07.24 20:39 Сейчас в теме
Спасибо, пригодилось!
4. Evil Beaver 8248 02.07.24 13:57 Сейчас в теме
Простите за некропостинг, но в коде есть ошибка.

Тест для числа 0.2 возвращает 0.224. Если поправить формулы экспоненты в строке "Экспонента =" и вычитать 126, то для чисел меньше единицы начинает работать правильно. А для чисел больше единицы - неправильно :(

Т.е. приведенный код работает для чисел > 1.0 и не работает для чисел < 1.0
Оставьте свое сообщение