gifts2017

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

Опубликовал Konstantin Korolyoff (kos) в раздел Программирование - Инструментарий

Два алгоритма перевода десятичного числа в другую систему исчисления от 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.* с учетом особенностей языков.

Скачать файлы

Наименование Файл Версия Размер
АлгоритмПеревода10числаВДругуюСистемуИсчисления 6
.ert 35,50Kb
04.06.14
6
.ert 2014.06.04 35,50Kb Скачать

См. также

Подписаться Добавить вознаграждение
Комментарии
1. Максим Шивирдинов (Ветер в поле) 21.07.15 00:18
Понадобилась функция для перевода из одного основания в другое.
Сначала написал свою, потом скачал это.

Вариант 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^31 - 1. Это чуть больше 2 миллиардов.
2. Максим Шивирдинов (Ветер в поле) 21.07.15 00:22
Ну и мой вариант, может кому пригодится:

Используются объекты из 1С++
глМД = СоздатьОбъект("MetaDataWork");
глМатематика = СоздатьОбъект("Математика");

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