Появилась необходимость для работы с бинарными файлами читать и писать вещественные числа (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));
Возврат ВещественноеЧисло;
КонецФункции