Как определить простое число в 1с
Рассмотрим один из примитивных типов, с которым приходится сталкиваться разработчикам на платформе 1С 8.3, – Число. В этой статье мы научимся задавать числа в коде, создавать реквизиты с типом число , получать случайное число, округлять числа и получать из числа с дробью целое число.
Тип число в 1С
Задать число в коде просто: нужно какой-то переменной просто присвоить определенное число.
Так задаётся целое число:
А так задаются дробные числа:
Над числами в коде можно выполнять простые арифметические операции: сложение, вычитание, умножение и деление.
Причем, как непосредственно над числами:
Так и над переменными с типом число:
Если нужно инвертировать число, т.е. поставить какому-то уже заданному числу обратный знак (например, было 5, стало -5), то его нужно умножить на -1.
Сделать это можно несколькими способами:
Если нам нужно создать реквизит какого-то объекта, с типом число, то в свойстве Тип реквизита нужно выбрать тип Число. На картинке ниже у справочника создан реквизит с типом Число.
А также задать его точность и длину.
Остановимся на точности и длине подробнее.
Точность – это максимальное количество знаков после запятой.
Длина – это максимальное количество разрядов в числе (включая знаки после запятой).
Например, если длина 5, а точность 3, то максимальное число будет 99,999.
Если длина 5, а точность 0, то – 99999.
А если длинна 3, а точность 3, то – 0,999. Т.е когда длинна равна точности мы не сможем задать число равное 1.
Когда мы в коде задаем переменную с типом Число, то мы не ограничиваем эту переменную по длине и точности, в тоже время для реквизита объекта с типом Число нужно это делать заранее. При разработке вы должны заранее предусмотреть, какие у реквизита числового типа будет длинна и точность.
Точно также, реквизит с типом число нужной длинны и точности можно создать на управляемой форме.
Случайное число в 1С
В платформе 1С 8.3 имеется возможность сгенерировать случайное целое число при помощи генератора случайных чисел, который так и называется ГенераторСлучайныхЧисел. Для генерации случайного числа нужно воспользоваться методом этого объекта СлучайноеЧисло.
Рассмотрим, простой пример генерации случайного числа.
В этом случае Число1 будет сгенерировано от 0 до 4294967295 (2^32 -1).
В примере выше метод СлучайноеЧисло без параметров, но у этого метода есть два параметра:
Оба параметра являются необязательных и с их помощью можно задать верхнюю и нижнюю границу генерации случайных чисел. Причем параметр НижняяГраница не может быть меньше нуля, а параметр ВерхняяГраница не может быть больше 4294967295.
Например, в этом случае будет сгенерировано случайное число от 1 до 100.
Округлить число в 1С
В платформе 1С имеется возможность округления чисел по определенному правилу. Для этих целей существует метод Окр. Этот метод является функцией, которая принимает число, нужное для округления, и возвращает округленное число. Данный метод имеет следующий синтаксис:
Число – число, которое будет округляться;
Разрядность – до какого количества знаков после запятой нужно округлить число (если разрядность равна 0, то число будет округлено до целого числа).
РежимОкругления – системное перечисление, которое имеет два значения: РежимОкругления.Окр15как10 – в этом случае 1.5 округляется до 1, РежимОкругления.Окр15как20 – 1.5 округляется до 2. Если этот параметр не задан, то по умолчанию 1.5 округляется до 2
В этом случае будет следующий результат:
Целое число в 1С
Если предыдущий метод округляет число, то также имеется возможность получать целое число, т.е. просто отбросить дробную часть числа. Делает это метод Цел. Данный метод является функцией, принимающей единственный параметр – число, у которого нужно отбросить дробную часть, и возвращающей полученное целое число.
Рассмотрим работу этого метод в сравнении с методом округления числа.
Должен получиться следующий результат:
Из результата вы видите, что нельзя использовать метод Окр для получения целого числа, он именно округляет и не всегда может дать требуемый результат. Для получения целого числа используйте метод Цел.
Степень числа в 1С
В платформе 1С имеется возможность возвести нужное число в степень. Делается это при помощи метода Pow, который является функцией со следующим синтаксисом.
Рассмотрим ряд примеров:
Из примеров видно, что мы можем возводить в положительную и отрицательную степень, а также степень может быть дробной.
Функции чисел в 1С
В платформе 1С 8.3 имеется другие функции пот работе с числами , познакомится с ними можно в синтаксис-помощнике. В подразделе Функции работы со значениями типа Число.
Другие статьи о примитивных типах:
Более подробно и основательно начальные вопросы программирования в 1С есть вы можете изучить в
Книга «Программировать в 1С за 11 шагов»
Изучайте программирование в 1С в месте с моей книгой «Программировать в 1С за 11 шагов»
Книга написана понятным и простым языком — для новичка.
- Книга посылается на электронную почту в формате PDF. Можно открыть на любом устройстве!
- Научитесь понимать архитектуру 1С;
- Станете писать код на языке 1С;
- Освоите основные приемы программирования;
- Закрепите полученные знания при помощи задачника.
О том как разрабатывать под управляемым приложением 1С, читайте в книге Книга «Основы разработки в 1С: Такси»
Отличное пособие по разработке в управляемом приложении 1С, как для начинающих разработчиков, так и для опытных программистов.
- Очень доступный и понятный язык изложения
- Книга посылается на электронную почту в формате PDF. Можно открыть на любом устройстве!
- Поймете идеологию управляемого приложения 1С
- Узнаете, как разрабатывать управляемое приложение;
- Научитесь разрабатывать управляемые формы 1С;
- Сможете работать с основными и нужными элементами управляемых форм
- Программирование под управляемым приложением станет понятным
Промо-код на скидку в 15% — 48PVXHeYu
Эти книги, плюс книга по программированию оперативного учета имеются в едином комплекте: комплект книг по разработке в 1С.
Только для читателей моего блога,
промо-код на скидку в 300 рублей на весь комплект: blog
Если Вам понравился этот урок, был полезен или помог решить какую-нибудь проблему, то Вы можете поддержать мой проект, перечислив любую сумму.
Войдите как ученик, чтобы получить доступ к материалам школы
Упражнения по внутреннему языку программирования 1С 8.3: простые числа
Автор упражнений и преподаватель школы: Владимир Милькин
Упражнение №6. Напишите программу, которая вводит от пользователя натуральное число, затем вычисляет является ли оно простым и выводит результат.
Натуральными называются числа, возникающие естественным образом при счёте: 1, 2, 3, 4, 5 . и так далее (более подробно, если вам интересно читайте здесь).
Натуральное число называется простым, если оно делится нацело (то есть без остатка) только на 1 и на самого себя (более подробно, если вам интересно читайте здесь).
- 2 - простое число, так как делится нацело только на 1 и на себя
- 3 - простое
- 4 - не является простым, так как делится без остатка не только на 1 и самого себя, но ещё и на 2
- 5 - простое
- 6 - не является простым
- и так далее.
Для ввода числа от пользователя используйте функцию "ВвестиЧисло".
Чтобы определить, что одно число делится на другое без остатка используйте операцию % (процент), которая находит остаток от деления чисел.
Для вывода результата пользователю используйте функцию "ОткрытьЗначение".
Для того, чтобы стало возможным использование этих модальных функций в нашей учебной базе выполните следующие инструкции:
1. Нажмите правой кнопкой мыши на элементе "Конфигурация" и выберите пункт "Свойства".
2. Внизу открывшейся справа панели найдите пункт "Режим использования модальности". Установите его значение в "Использовать". Вы читаете ознакомительную версию урока, полноценные уроки находятся здесь.
3. Нажмите на значок дискеты, чтобы сохранить изменения.
Ввести от пользователя число. Пробежаться по всем числам от 2 до (введённого числа - 1) и проверить делится ли без остатка введённое число на хотя бы одно из них. Если не делится, то число простое. Если делится хотя бы на одно - число не является простым.
Эталонное решение. Сначала пишем код сами, проверяем на компьютере (как и все примеры программ из уроков), только потом сверяемся
Войдите на сайт как ученик
Упражнение №7а. Напишите программу, которая выводит все простые числа от 1 до 1000.
Проверять отдельно взятые числа на простоту мы уже научились в предыдущем упражнении. Что теперь может быть проще объявить цикл от 2 до 1000 и проверить каждое из этих чисел на простоту?
Пробежаться в цикле от 2 до 1000 и уже известным нам способом проверить каждое из этих чисел на простоту. Все простые числа вывести пользователю.
Эталонное решение. Сначала пишем код сами, проверяем на компьютере (как и все примеры программ из уроков), только потом сверяемся
Войдите на сайт как ученик
Для учеников
Второй модуль - самый сложный в школе. Если вы не программировали ранее - приготовьтесь к тому, что не сможете решить некоторые из задач с первого раза и без подсказок.
Поэтому вовремя останавливайтесь и спрашивайте преподавателя, если что-то не понятно даже с подсказками.
В крайнем случае, пройдите все оставшиеся модули школы, а затем вернитесь с новыми силами к решению задач второго модуля.
На вопросы учеников — отвечаю по почте, но прежде загляните в ЧАВО (ссылка) .
Что может быть проще простых чисел ? По определению, целое число называется простым, если оно не может быть представлено, как произведение двух меньших чисел. Единственное четное простое число - 2. Все остальные простые числа нечетные. Самый древний алгоритм поиска простых чисел получил название "решето Эратосфена". Это известная история и останавливаться на ней не будем. Сразу перейдем к заявленной теме, а именно, поиску простых чисел с помощью запроса на встроенном языке платформы 1С:Предприятие. Исходным объектом для поиска будет таблица натуральных чисел в диапазоне от 1 до заданного верхнего предела. Подобную таблицу, можно формировать в запросе , но мы упростим себе жизнь и заполним её с помощью операторов встроенного языка.
Рассмотрим первый алгоритм. Построим соединение двух одинаковых таблиц, сформированных на первом этапе. В характеристиках связи зададим условие, что левый множитель меньше или равен правому, плюс потребуем,чтобы произведение этих чисел было меньше максимального числа в исходной таблице. Для каждой образованной пары чисел вычислим произведение.Ниже приведен пример для набора чисел меньше 9. Исходная таблица
НатуральноеЧисло |
---|
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
Пары чисел, образованные при внутреннем соединении таблицы со своей копией при заданных ограничениях.
Левое | Правое | Произведение |
---|---|---|
1 | 1 | 1 |
1 | 2 | 2 |
2 | 2 | 4 |
1 | 3 | 3 |
2 | 3 | 6 |
3 | 3 | 9 |
1 | 4 | 4 |
2 | 4 | 8 |
1 | 5 | 5 |
1 | 6 | 6 |
1 | 7 | 7 |
1 | 8 | 8 |
1 | 9 | 9 |
Исходная таблица содержала 9 строк, итоговая 13. Среди чисел в колонке Произведение есть повторяющиеся. Это числа 4,6 и 9. Числа 1,2,3,5,7 встречаются только один раз. Единицу из этого ряда надо исключить. Оставшиеся четыре числа будут первыми в ряду простых чисел. Приведем текст запроса:
Запрос возвращает количество простых чисел в первоначальном диапазоне.Приведенный алгоритм отличается простотой, но увы, слишком медленный. Постараемся придумать, что-то быстрее.
Как проверить, что число А делится без остатка на число Б. Во встроенном языке есть оператор %, который возвращает остаток от деления. В языке запросов такая опция отсутствует. Поэтому воспользуемся следующим приемом :
Если это выражение истинно, то Б является делителем числа А. Идея запроса следующая. Организуем внутреннее соединение исходной таблицы со своей копией, где в качестве условия выступает представленная выше проверка на делимость. Понятно, что число Б должно быть меньше числа А. Более того, число Б должно быть меньше корня квадратного из А. Квадратный корень в запросе мы вычислить не можем, но мы можем найти целое приближение к квадратному корню.
Сформируем таблицу с квадратами наших исходных чисел.Теперь соединим данную таблицу с исходной. Полученную набор сгруппируем по исходным числам, а для квадратов применим функцию МИНИМУМ(). Текст запроса приведен ниже:
Во временной таблице мКорни в колонке Н содержится число из исходного набора, а в колонке Корень, минимальное число,квадрат которого больше или равен Н. А теперь соберем все вместе:
Любопытно проверить, как различаются скорость выполнения первого и второго запроса (время в миллисекундах):
Верхняя граница | 1000 | 2000 | 3000 | 4000 | 5000 |
---|---|---|---|---|---|
Вариант 1 | 492 | 795 | 1229 | 2314 | 3061 |
Вариант 2 | 651 | 954 | 1644 | 2955 | 4364 |
Видим, что первый вариант запроса отрабатывает быстрее. Для второго можно "проредить" исходные данные, а именно убрать все четные числа кроме двойки (это уже элемент алгоритма "решето Эратосфена").
Очевидно, что после такой операции скорость должна увеличиться, что и показывают замеры (время в миллисекундах):
Верхняя граница | 1000 | 2000 | 3000 | 4000 | 5000 |
---|---|---|---|---|---|
Вариант 1 | 492 | 795 | 1229 | 2314 | 3061 |
Вариант 2 (ускоренный) | 268 | 842 | 1163 | 1373 | 1587 |
Посмотрев решения от Сергея (ildarovich) , решил добавить экзотику в виде решета Аткина. Максимальное значение верхней границы в приведенном примере - 100 000. Параметры запроса - Граница и КореньИзГраницы. Все простые числа
Нам осталось сказать, где это можно использовать. Разумеется, ни в одной типовой конфигурации такие задачи не встречаются. Но подобный вопрос может встретиться на собеседовании при приеме на работу. Теперь вы знаете, как на него ответить.
Чтобы более качественно понимать, как работает механизм соединений, решил написать поиск простых чисел через запрос, используя классический алгоритм этой публикации подобные решения, однако они сегодня менее производительны (для 10 6 не дождался вычислений). В новой версии платформы 8.3.20 в языке запросов появились новые функции возведения в степень/вычисление квадратного корня и округления до целого без лишних конструкций. Поэтому решение получается более простым и быстрым. Кроме того добавлено больше элементов оптимизации. Также приведена сравнительная характеристика по скорости вычисления для разных СУБД.
Публикация состоит из тре х разделов:
- Краткое описание алгоритма
- Решение
- Скорость вычисления и сравнение производительности вычислений с двумя основными СУБД, файловым вариантом, чистым MSSQL и императивным кодом на 1С.
Простым числом называется такое число, которое больше единицы и без остатка делится только на единицу и самого себя. Наиболее простой вариант нахождения простых чисел - это брать последовательно каждое число и проверять его делимость на все предыдущие. Быстро приходим к выводу, что проверять все числа избыточно. Как минимум, нужно идти до половины (понятно, что при делении числа N на число Целое(N / 2) + k целового не получится), а если быть точнее, то делить будем только до квадратного из искомого числа. По одной из теорем наименьший положительный и отличный от единицы делитель составного числа a не превосходит его квадратный корень.
Запрос построен из двух частей:
- Генерация чисел, которые будем проверять на простоту
- Вычисление, является ли число простым
В качестве параметра запроса передаем верхнюю границы последовательности.
Генерация чисел осуществляется классическим способом через декартово произведение. Но написано немного хитро, чтобы быстро работало при любых значениях параметра. Если не отсеивать ненужные объединения при мелком значении параметра, то будет затрачиваться много времени на генерацию последовательности (чтобы всегда десять миллионов чисел не генерировалось). Поэтому использую полное соединение по Истина. Если не указывать соединения, то результат выборки будет только тогда, когда у всех выбираемых таблиц есть хотя бы одно значение. При полном соединении по Истина всегда выберутся данные хотя бы с одной таблицы, если там что-то есть.
Добавляем +2 внутри первого запроса, где получаются числа, чтобы генерация началась с двойки, так как 1 - это не простое число.
Далее отсекаем все числа, оканчивающиеся на четные цифры и кратные 5. Такие числа точно не будут являться простыми, нет смысла их рассматривать.
Не уверен, что здесь нужен индекс. Кажется, что он тут не срабатывает. Однако на скорость работы его наличия не влияет по тестам, так что оставил.
Генерируется максимум до 10 7 чисел.
Далее соединяем эту числовую последовательность саму с собой по условию При этом не будем рассматривать числа, кратные 2, 3, 5 или 7. Такая проверка в условии соединения будет выполняться быстрее, чем дальнейшее рассмотрение таких чисел. Выигрыш в скорости почти в 2 раза.
Выражение N - M * ЦЕЛ(N / M) равносильно выражению N % M (это остаток от деления).
В условии ИМЕЮЩИЕ помещаем выражение, которое возвращает остаток от деления числа, которое мы выбираем, на числа второй таблицы. Если все числа поделились с остатком, то МИНИМУМ вернет число большее нуля.
В объединениях добавляем нерассмотренные простые числа, которые выпали на уровне условия соединения.
Также решил написать запрос на чистом SQL (используя T-SQL в MSSQL). Чтобы сравнить производительность запроса, написанного через 1С-овскую обертку и напрямую. Разница в производительность оказалось огромной. Для того, чтобы результат сравнения был релевантный, то сделал также вариант запроса без использования оператора "%". Так как оператор остатка от деления почему-то не завезли в язык запросов 1С.
Здесь, в T-SQL, созданный вручную индекс во временной таблице работает. Скорость выполнения с индексом выше почти в 1,5 раза.
Далее представлена скорость вычислений в секундах для разных размеров последовательности и разных СУБД (Postgres и MSSQL), включая файловый вариант. Код для варианта с использованием императивного языка был использован из этой публикации.
N | 100 | 10 3 | 10 4 | 10 5 | 10 6 | 10 7 |
---|---|---|---|---|---|---|
1С+Файловый режим | 0.006 | 0.02 | 0.22 | 5.07 | 125 | 3550 (59.2 мин) |
1С+Postgres | 0.532 | 0.52 | 0.63 | 2.72 | 50 | 1356 (22.6 мин) |
1С+MSSQL | 0.003 | 0.01 | 0.11 | 1.60 | 37 | 1009 (16.8 мин) |
MSSQL без "%" | 0.037 | 0.04 | 0.08 | 0.66 | 13 | 347 (5.8 мин) |
MSSQL с "%" | 0.009 | 0.02 | 0.07 | 0.54 | 12 | 309 (5 мин) |
Императивный код 1С | 0.004 | 0.01 | 0.09 | 1.00 | 10 | 112 (2 мин) |
На графике наглядней видна разница в скорости вычислений для режимов работы с разными СУБД (здесь по горизонтали - размер последовательности, по вертикали - время выполнения в секундах).
Отдельно приведу график сравнения выполнения аналогичного кода на чистом MSSQL и через 1С-овскую обертку.
Как-то раз с коллегой зашел разговор о том почему в платформе не реализована функция получения модуля числа, ведь для учетной системы это довольно нужная вещь ( скорее всего разработчики платформы еще заняты написанием функции инкрементации и им не до этого , кстати если у вас есть предположения, то пишите в комментариях) и мы обсуждали, что способов написания такой функции может быть несколько и я решил посчитать, а сколько же их можно придумать. Конечно большинство из них "высосаны из пальца" и не могут использоваться на практике в виду здравого смысла, но нас это не останавливает), итак, поехали!
1.Наиболее логичный и распространенный способ, проверяем на превышение нуля и инвертируем значение при необходимости
2.Также довольно распространенный способ, используем функцию Макс()
На этом адекватные способы закончились) и начинаются извращения начинаем использовать
3.Перевести в строку, избавиться от минуса и конвертировать обратно в число?! Легко!
4.Далее вспоминаем, что можем использовать com-объекты, а это открывает нам удивительные возможности
Изначально я использовал такой код:
Но в серверном контексте я получил ошибку отсутствия класса из-за различия в разрядности, а делать обертку на корпоративном сервере не хотелось, поэтому я решил использовать другой com, а именно regexp
5.Используем список значений и сортируем, почему нет?
6.Используем запрос, в принципе это нормальный способ и т.к. вычисление производится на стороне СУБД я решил его тоже включить
7.Далее вспоминаем из курса школьной программы гуглим, что
Модуль числа a – это арифметический квадратный корень из квадрата числа a , исходя из этого пишем функцию
8.Используем Формат , чтобы избавиться от минуса и используем функцию Вычислить
Да остановись уже!
9.Здесь вообщем то уже читерство, используем ОписаниеТипов с допустимым знаком "+" и если после приведения результат = 0, то инвертируем значение
10.И напоследок используем такой же подход, перехватываем исключение в функции, где параметр положительное число, например, СлучайноеЧисло
И в заключение этой "шедевральной" статьи график (обработка во вложении) по скорости выполнения на 10000 итерациях. Версия платформы: 8.3.13.1513
Ожидаемо запрос и com самый медленный ввиду инициализации объектов, а математика самая быстрая.
Знаешь еще способы - пиши в комментах!
На этом дорогие друзья у меня все, и кстати это моя первая статья ( я долго копил свой опыт, чтобы поделиться им с сообществом ), надеюсь, ее шуточный характер не встанет мне боком)
Читайте также: