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

11.07.19

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

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

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование По подписке [?] Купить один файл
10 способов получить модуль числа (а может и больше):
.epf 8,03Kb
1
1 Скачать (1 SM) Купить за 1 850 руб.

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

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 самый медленный ввиду инициализации объектов, а математика самая быстрая.

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

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

 

модуль числа интересное

См. также

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

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

21.05.2024    20110    dimanich70    81    

144

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

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

28.08.2023    14726    YA_418728146    7    

166

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

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

2 стартмани

22.08.2023    3578    56    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    18476    171    sapervodichka    112    

135

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

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

18.07.2022    8370    quazare    8    

111

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

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

28.05.2022    10434    milkers    11    

98

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

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

25.04.2022    19160    quazare    11    

139
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. DJDUH 17 11.07.19 13:11 Сейчас в теме
1.Наиболее логичный и распространенный способ, проверяем на превышение нуля и инвертируем значение при необходимости

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

Возврат ?(Число >= 0, Число, -Число);

КонецФункции // МодульЧисла()


С точки зрения математики
>=0
.
3. ahahaev 11.07.19 14:09 Сейчас в теме
(1) Либо ?(Число < 0, -Число, Число).

Чтобы произносить было короче :D
4. sam441 225 11.07.19 14:14 Сейчас в теме
2. json 3349 11.07.19 13:43 Сейчас в теме
чисто как еще один способ

МодульЧисла = Число(СтрЗаменить(СтрЗаменить(Число, "-", ""), Символ(160), ""));
6. SlavaKron 11.07.19 14:43 Сейчас в теме
(2) Так быстрее:
МодульЧисла = Число(СтрЗаменить(XMLСтрока(Число), "-", ""));
sp18s; json; +2 Ответить
5. singlych 11.07.19 14:37 Сейчас в теме
Возврат ?(СтрДлина(Число) > СтрДлина(-Число), -Число, Число)
D.B.Sokolov; DrAku1a; rintik; Sergynia; d.menyailov@ngslab.ru; tulakin_s; CyberCerber; sam441; ahahaev; +9 Ответить
7. singlych 11.07.19 15:17 Сейчас в теме
А еще прикольно с БСП, правда только для целых от -99 до 999
СтроковыеФункцииКлиентСервер.ПреобразоватьЧислоВАрабскуюНотацию(СтроковыеФункцииКлиентСервер.ПреобразоватьЧислоВРимскуюНотацию(Число))
8. SlavaKron 11.07.19 15:28 Сейчас в теме
запрос и com самый медленный ввиду инициализации объектов

Вы каждую итерацию их инициализировали? Так не пойдёт, такие вещи кэшировать надо.
Мои результаты на 1 млн. итераций (в мс):
Число > 0 391
Макс 393
СтрЗаменить 4356
Число(СтрЗаменить(XMLСтрока 2179
СтрДлина 3873
Лев 1200
Sqrt 1115
user774630; +1 Ответить
9. sam441 225 11.07.19 15:48 Сейчас в теме
(8) Была такая мысль, но мы же пишем независимую функцию, работающую без дополнительных настроек, естественно, я знаю про кэш, да и в контексте "несерьезности" задачи вряд ли это имеет смысл :)
d.menyailov@ngslab.ru; user774630; +2 Ответить
10. ildarovich 7930 11.07.19 22:01 Сейчас в теме
Вот два варианта на основе "индикаторной" функции:
Функция МодульЧисла21(Число)
	
	Возврат ((Число > 0) * 2 - 1) * Число
	
КонецФункции

Функция МодульЧисла22(Число)
	
	Возврат (Число > 0) * Число - (Число < 0) * Число
	
КонецФункции
Показать
И для разнообразия
Функция МодульЧисла23(Число)
	
	Возврат - Мин(Число, - Число)
	
КонецФункции
wbazil; D.B.Sokolov; aleksey2; DrAku1a; rintik; d.menyailov@ngslab.ru; dabu-dabu; Ibrogim; spacecraft; testnv0; mvxyz; singlych; CyberCerber; tulakin_s; plevakin; user811769; ice-net; alalsl; Serj1C; ahahaev; sam441; json; PowerBoy; awk; RustIG; +25 Ответить
27. spacecraft 15.07.19 14:22 Сейчас в теме
(10)
Возврат (Число > 0) * Число - (Число < 0) * Число

это можно упростить:
Возврат (Число*((Число>0)-(Число<0)))
D.B.Sokolov; Crazy_Max; dabu-dabu; json; ildarovich; +5 Ответить
11. RustIG 1747 11.07.19 22:07 Сейчас в теме
(0) шуточные задачки развивают логическое мышление :)
D.B.Sokolov; rpgshnik; sam441; pm74; +4 Ответить
12. acanta 11.07.19 23:28 Сейчас в теме
Все, о чем молчат гусары...
13. user856012 14 12.07.19 00:55 Сейчас в теме
Неее, это другое: "Баловство это, барин, жениться вам надо..." (с)
14. kredko 20 12.07.19 06:44 Сейчас в теме
Якубович и Спанчбоб - самые главные персонажи в этой статье.
15. madonov 259 12.07.19 07:52 Сейчас в теме
18. sam441 225 12.07.19 09:44 Сейчас в теме
(15) Ну как бы в самом начале написал just for fun)
OldClay; acanta; +2 Ответить
16. pm74 203 12.07.19 08:29 Сейчас в теме
шутки ради
Функция МодульЧисла_00000001(Число)  // для |Число| > 0.00000001
     Возврат -100000000*(Число-(Число+0.00000001)%(Число-0.00000001)-(Число-0.00000001)%(Число+0.00000001))*Число;
КонецФункции
17. user811769 14 12.07.19 09:12 Сейчас в теме
спасибо, повеселили с утра пораньше =)
19. rpgshnik 3795 12.07.19 10:26 Сейчас в теме
Запросы рулят, говорили они :)
20. scientes 295 12.07.19 11:08 Сейчас в теме
Pow(10,0,5*Log10(Число*Число))
21. пользователь 12.07.19 11:17
Сообщение было скрыто модератором.
...
22. пользователь 12.07.19 13:08
Сообщение было скрыто модератором.
...
23. collider 12.07.19 14:03 Сейчас в теме
Функция МодульЧисла(Число)
    ДобавляемыеРеквизиты	= Новый Массив;
    НеотрицательноеЧисло = Новый РеквизитФормы("НеотрицательноеЧисло",	Новый ОписаниеТипов("Число", , , Новый КвалификаторыЧисла(10, 3, ДопустимыйЗнак.Неотрицательный)));
    ДобавляемыеРеквизиты.Добавить(НеотрицательноеЧисло);
    ИзменитьРеквизиты(ДобавляемыеРеквизиты);
	ЭтаФорма.НеотрицательноеЧисло = Число;   
	Возврат ?(ЭтаФорма.НеотрицательноеЧисло = 0, -Число, Число); 	
КонецФункции
24. A1WEB 59 14.07.19 01:41 Сейчас в теме
Для особо искушенных: (x ^ (x >> 31)) - (x >> 31)
Serg2000mr; sam441; Yashazz; +3 Ответить
25. FesenkoA 58 15.07.19 12:05 Сейчас в теме
Можно еще создать макет, в котором заполнить все положительные числа, потом в процессе загрузить колонку в массив и проверить на наличие числа в массиве, если нету - умножить на (-1).
26. sam441 225 15.07.19 12:48 Сейчас в теме
(25)
Можно еще создать макет, в котором заполнить все положительные числа
идеально:) какое последнее число?)
28. FesenkoA 58 15.07.19 15:56 Сейчас в теме
(26) 99999999999999999999999999999999,99999999999999999999999999999999

[32,32]
29. FesenkoA 58 15.07.19 17:19 Сейчас в теме
Опять же, можно воспользоваться АПИ (типа http://mobmath.appspot.com), передать туда уравнение и получить ответ
30. FesenkoA 58 15.07.19 17:23 Сейчас в теме
Модуль=?(Pow(10, число)>1,1,-1)*число;
31. qwinter 683 16.07.19 12:36 Сейчас в теме
Какие то жуткие цифры на диаграмме)) Вы не в отладке тест сделали случайно?)) Я советую провести тест без нее и выложить результаты, т.к. первый метод должен выигрывать у второго, пусть и немного.
32. user649848_v.ilkaev 09.06.21 17:11 Сейчас в теме
На диаграмме результаты ком - объекта нужно сдвинуть праве.. Тогда эта диаграмма будет гораздо красноречивее.
33. user597030_myyashik2 17.08.21 05:41 Сейчас в теме
Всем здрасьте! Я может чего-то не понимаю, но почему никто не сказал, что можно просто умножить на -1?
34. Snouphruh 31.08.21 13:27 Сейчас в теме
35. shibudo 11.10.21 16:07 Сейчас в теме
(34)
1) xor rax, -1 это not rax, та же операция, но размер меньше за счет отсутствия константы -1
2) not rax и inc rax - оба эти действия выполняет neg rax

Минус в том, что вы положительное число превратите в отрицательное, а отрицательное в положительное. А исходно стояла задача взять модуль числа.
36. Snouphruh 16.11.21 08:31 Сейчас в теме
(35) мой косяк.

тогда уж так:

mov rax, <наше число>
cqo
xor rax, rdx
sub rax, rdx
37. user1516660 26.12.21 13:47 Сейчас в теме
(36) А теперь как это выполнить в 1С?
38. Automatik 959 06.10.22 06:01 Сейчас в теме
Странно, что в платформе это до сих пор не реализовано, сколько бы времени сэкономили на комментах!
ValeraEm; +1 Ответить
39. Serg2000mr 670 25.05.23 15:19 Сейчас в теме
После прочтения всех комментариев, у меня размылось понимание слова число и остался один вопрос: А писло чесать? :D
40. ValeraEm 139 31.05.23 10:15 Сейчас в теме
Вот что меня удивляет, простые/общеупотребительные математические функции - а приходится изобретать велосипед
Оставьте свое сообщение