Перевод десятичного числа в HEX, BIN, OCT, _IdToStr и другие системы

Два алгоритма перевода десятичного числа в другую систему исчисления от 2 до 36 только средствами 1С (без ВК)

Задача вроде бы тривиальная.

Но не нашел БЫСТРОГО ответа на вопрос :

 

Как перевести средствами встроенного языка 1С 10-ное число в HEX ?

Ну и заодно — в BIN, в OCT и в другие системы исчисления ?

 

Пришлось достать учебники по математике Laughing и написать эту статью.

В результате — получил 2ва алгоритма:

— первый : с рекурсивными вызовами после остатка от деления по основанию Х

— второй : через логарифмы с циклом

 

Коротко о главном:

1) первый алгоритм — получился быстрее. Вот результаты:

   

 //Вариант 1: время = 77.697 сек , Обработано чисел = 1 000 000
//65535 (HEX) = FFFF
//65535 (BIN) = 1111111111111111
//65535 (OCT) = 177777
//65535 (_IdToStr) = 1EKF
//на одно вычисление = 0,000077697 сек для случая _IdToStr

//Вариант 2: время = 85.547 сек, Обработано чисел = 1 000 000
//65535 (HEX) = FFFF
//65535 (BIN) = 1111111111111111
//65535 (OCT) = 177777
//65535 (_IdToStr) = 1EKF
// на одно вычисление = 0,000085547 сек для случая _IdToStr
 

 

2) второй алгоритм (если честно) был подсмотрен в реализации SQL-функции для _IdToStr
и модифицирован для универсальности (не только для основания 36, а для любого основания).
Эта SQL-функция широко используется в сообществе 1С++
(К сожалению, автора-первооткрывателя : не знаю, поэтому — поклон ему и всем участникам проекта Laughing )

 

Алгоритмы (что во вложении) написаны для 1С.7.7

Алгоритмы универсальные: поэтому легко переделать для 1С8.* с учетом особенностей языков.

2 Comments

  1. Ветер в поле

    Понадобилась функция для перевода из одного основания в другое.

    Сначала написал свою, потом скачал это.

    Вариант 2 содержит ошибку.

    Когда число = Основание в степени Н, то происходит лишняя итерация.

    Ошибка тут:

    Знч = цел(Ln(ч10)/Ln(чОснование)) +1

    Для i=1 По Знч-1 Цикл

    чСтепень = чСтепень*чОснование;

    КонецЦикла;

    Вот демонстрация:

    Вариант 1: время = 0.475, КвоИтераций=10000

    1679616 = 19A100

    1679616 = 110011010000100000000

    1679616 = 6320400

    1679616 = 10000

    Вариант 2: время = 0.465, КвоИтераций=10000

    1679616 = 19A100

    1679616 = 110011010000100000000

    1679616 = 6320400

    1679616 = 000

    Вариант 3: время = 0.046, КвоИтераций=10000

    1679616 = 19A100

    1679616 = 110011010000100000000

    1679616 = 6320400

    1679616 = 10000

    Благо это самый тормозной алгоритм и его вряд ли кто использовал.

    Просто будьте внимательнее.

    P.S. 3-й вариант мой, но он использует еще и внешние компоненты.

    К сожалению, в 1С++ используется сильно ограниченная версия перевода числа из одной системы в другую.

    Она только для чисел до 2#k8SjZc9Dxk31 — 1. Это чуть больше 2 миллиардов.

    Reply
  2. Ветер в поле

    Ну и мой вариант, может кому пригодится:

    Используются объекты из 1С++

    глМД = СоздатьОбъект(«MetaDataWork»);
    глМатематика = СоздатьОбъект(«Математика»);
    
    Функция глПеревестиСтрИзОдногоОснованияВДругое(Знач СтрЧисло, ОснованиеИз, ОснованиеВ) Экспорт
    
    СтрСимволов = «0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ»;
    
    //сначала переведем в число
    Если ОснованиеИз = 10 Тогда
    Число10 = Число(СтрЧисло); //небольшая оптимизация
    
    Иначе
    СтрЧисло = СокрЛП(СтрЧисло);
    
    //оптимизация: вычислим макс. кол-во знаков, кот. сможет осилить функция глМД.СтрокуВЧисло
    Число10 = 0;
    МощностьПозиции = 0;
    МаксКолвоСимволов = Цел(Лог(2147483646) / Лог(ОснованиеИз));
    
    Пока СтрДлина(СтрЧисло) > 0 Цикл
    Если МощностьПозиции = 0  Тогда
    МощностьПозиции = 1;
    
    Иначе
    МощностьПозиции = МощностьПозиции * глМатематика.POW(ОснованиеИз, МаксКолвоСимволов);
    КонецЕсли;
    
    Число10 = Число10 + глМД.СтрокаВЧисло(Прав(СтрЧисло, МаксКолвоСимволов), ОснованиеИз) * МощностьПозиции;
    СтрЧисло = Лев(СтрЧисло, СтрДлина(СтрЧисло) — МаксКолвоСимволов);
    КонецЦикла;
    КонецЕсли;
    
    СтрРезультата = «»;
    Пока Число10 > 2147483646 Цикл
    СтрРезультата = Сред(СтрСимволов, Строка(1 + (Число10 % ОснованиеВ)), 1) + СтрРезультата;
    Число10 = Цел(Число10 / ОснованиеВ);
    КонецЦикла;
    
    Возврат глМД.ЧислоВСтроку(Число10, ОснованиеВ) + СтрРезультата;
    
    КонецФункции //глПеревестиСтрИзОдногоОснованияВДругое

    Показать

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *