Каталог решений - 10 способов получить модуль числа (а может, и больше)

10 способов получить модуль числа (а может, и больше)

10 способов получить модуль числа (а может, и больше)

В наличии

Пишем функцию вычисления модуля числа. Сколько способов существует? Давайте посчитаем!

Категория:

Описание

Всем привет, сразу

DISCLAIMER: Данная статья носит исключительно развлекательный характер, не несет в себе никакой практической пользы и написана только для того, чтобы срубить плюсов just for fun:)

Как-то раз с коллегой зашел разговор о том почему в платформе не реализована функция получения модуля числа, ведь для учетной системы это довольно нужная вещь (скорее всего разработчики платформы еще заняты написанием функции инкрементации и им не до этого, кстати если у вас есть предположения, то пишите в комментариях) и мы обсуждали, что способов написания такой функции может быть несколько и я решил посчитать, а сколько же их можно придумать. Конечно большинство из них "высосаны из пальца" и не могут использоваться на практике в виду здравого смысла, но нас это не останавливает), итак, поехали!

1.Наиболее логичный и распространенный способ, проверяем на превышение нуля и инвертируем значение при необходимости

Функция МодульЧисла1(Число)

	Возврат ?(Число >= 0, Число, -Число);
		
КонецФункции // МодульЧисла()

2.Также довольно распространенный способ, используем функцию Макс()

Функция МодульЧисла2(Число)
	
	Возврат Макс(Число, -Число);
		
КонецФункции // МодульЧисла()

На этом адекватные способы закончились) и начинаются извращения начинаем использовать

3.Перевести в строку, избавиться от минуса и конвертировать обратно в число?! Легко!

Функция МодульЧисла3(Число)
	
	ЧислоСтрокой = Формат(Число, "ЧРД=.; ЧН=; ЧГ=");
	ЧислоСтрокой = СтрЗаменить(ЧислоСтрокой, "-", "");
		
	Возврат Число(ЧислоСтрокой);
				
КонецФункции // МодульЧисла()

4.Далее вспоминаем, что можем использовать com-объекты, а это открывает нам удивительные возможности

Изначально я использовал такой код:

ЧислоСтрокой = Формат(Число, "ЧРД=.; ЧН=; ЧГ=");
Script = Новый COMОбъект("MSScriptControl.ScriptControl");
Script.Language = "javascript";
Script.Eval(СтрШаблон("var abs = Math.abs(%1);",ЧислоСтрокой));
	
Возврат Script.CodeObject.abs;	

Но в серверном контексте я получил ошибку отсутствия класса из-за различия в разрядности, а делать обертку на корпоративном сервере не хотелось, поэтому я решил использовать другой com, а именно regexp

Функция МодульЧисла4(Число)
	
	RegExp = Новый COMОбъект("VBScript.RegExp");
	RegExp.Global 		= Истина;
	RegExp.IgnoreCase 	= Истина;
	RegExp.Pattern = "\d+[.,]?\d+";
	
	Matches = RegExp.Execute(Число);
	Если Matches.Count() > 0 Тогда
		Возврат Число(Matches.Item(0).Value);
	Иначе
		ВызватьИсключение("Нет вхождения строки");
	КонецЕсли;
	
КонецФункции // МодульЧисла()

5.Используем список значений и сортируем, почему нет?

Функция МодульЧисла5(Число)
	
	СписокЗначений = Новый СписокЗначений;
	СписокЗначений.Добавить(Число);
	СписокЗначений.Добавить(-Число);
	СписокЗначений.СортироватьПоЗначению(НаправлениеСортировки.Убыв);
	
	Возврат СписокЗначений[0].Значение;
			
КонецФункции // МодульЧисла()

6.Используем запрос, в принципе это нормальный способ и т.к. вычисление производится на стороне СУБД я решил его тоже включить

Функция МодульЧисла6(Число)
	
	Запрос = Новый Запрос;
	Запрос.Текст = 
		"ВЫБРАТЬ
		|	ВЫБОР
		|		КОГДА &Число >= 0
		|			ТОГДА &Число
		|		ИНАЧЕ -&Число
		|	КОНЕЦ КАК Модуль";
	
	Запрос.УстановитьПараметр("Число", Число);
	РезультатЗапроса = Запрос.Выполнить();
	ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
	ВыборкаДетальныеЗаписи.Следующий();
	
	Возврат ВыборкаДетальныеЗаписи.Модуль;
			
КонецФункции // МодульЧисла()

7.Далее вспоминаем из курса школьной программы гуглим, что

Модуль числа a – это арифметический квадратный корень из квадрата числа a, исходя из этого пишем функцию

Функция МодульЧисла7(Число)
	
	Квадрат = Pow(Число, 2);
	Корень  = Sqrt(Квадрат);
	
	Возврат Корень;
			
КонецФункции // МодульЧисла()

8.Используем Формат, чтобы избавиться от минуса и используем функцию Вычислить 

Функция МодульЧисла8(Число)
	
	ЧислоСтрокой = Формат(Число, "ЧРД=.; ЧН=; ЧГ=; ЧО=0");
	Возврат Вычислить("0+"+ЧислоСтрокой);
		
КонецФункции	

Да остановись уже!

9.Здесь вообщем то уже читерство, используем ОписаниеТипов с допустимым знаком "+" и если после приведения результат = 0, то инвертируем значение

Функция МодульЧисла9(Число)
	
	ЧислоСтрокой = Формат(Число, "ЧРД=.; ЧН=; ЧГ=");
	Подстроки    				= СтрРазделить(ЧислоСтрокой, ".");
	ЧислоРазрядов 				= СтрДлина(Подстроки[0]);
	ЧислоРазрядовДробнойЧасти 	= 0;
	Если Подстроки.Количество() > 1 Тогда
		ЧислоРазрядовДробнойЧасти = СтрДлина(Подстроки[1]);
	КонецЕсли;	
	КвалификаторЧисла = Новый КвалификаторыЧисла(ЧислоРазрядов, ЧислоРазрядовДробнойЧасти, ДопустимыйЗнак.Неотрицательный);
	ТипЧисло = Новый ОписаниеТипов("Число", КвалификаторЧисла);
	Если ТипЧисло.ПривестиЗначение(Число) = 0 Тогда
		Возврат -Число;
	Иначе	
		Возврат Число;
	КонецЕсли;	
				
КонецФункции // МодульЧисла()

Все? Нет

10.И напоследок используем такой же подход, перехватываем исключение в функции, где параметр положительное число, например, СлучайноеЧисло

Функция МодульЧисла10(Число)
	
	ГСЧ = Новый ГенераторСлучайныхЧисел;
	Попытка
		СлучайноеЧисло = ГСЧ.СлучайноеЧисло(0, Число);
		Возврат Число;
	Исключение
		Возврат -Число;
	КонецПопытки;
	
КонецФункции	

И в заключение этой "шедевральной" статьи график (обработка во вложении) по скорости выполнения на 10000 итерациях. Версия платформы: 8.3.13.1513

Ожидаемо запрос и com самый медленный ввиду инициализации объектов, а математика самая быстрая.

Знаешь еще способы — пиши в комментах!

На этом дорогие друзья у меня все, и кстати это моя первая статья (я долго копил свой опыт, чтобы поделиться им с сообществом), надеюсь, ее шуточный характер не встанет мне боком)

 

has been added to your cart:
Оформление заказа