К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как найти простые числа в 1С: алгоритмы, код и оптимизация

Как найти простые числа в 1С: проверка делителями, решето Эратосфена, готовые процедуры на встроенном языке, оптимизация и типичные ошибки.

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

Существует два базовых подхода: проверка каждого числа перебором делителей и решето Эратосфена, которое находит все простые числа диапазона за один проход. Первый подходит для единичных проверок, второй — когда нужен список простых чисел до заданной границы. Ниже разобраны оба метода с готовым кодом, который можно вставить в общий модуль или обработку.

Важный нюанс: встроенный язык 1С работает медленнее компилируемых языков, поэтому для больших диапазонов (миллионы чисел) стоит учитывать производительность и ограничивать область поиска. Для типовых задач — до нескольких сотен тысяч чисел — приведённые решения работают за секунды.

Как проверить, является ли число простым

Наивный способ — перебрать все делители от 2 до N−1 — работает, но избыточен. Достаточно проверить делители до квадратного корня из числа: если у числа есть делитель больше корня, то парный ему делитель обязательно меньше корня и уже был найден. Это сокращает количество итераций с N до примерно √N.

Дополнительная оптимизация — отдельно обработать чётные числа: если число больше 2 и делится на 2, оно сразу составное. После этого перебирать можно только нечётные делители с шагом 2, что вдвое уменьшает число итераций.

Готовая функция для общего модуля:

Функция ЭтоПростоеЧисло(Число) Экспорт

Если Число < 2 Тогда

Возврат Ложь;

КонецЕсли;

Если Число = 2 Тогда

Возврат Истина;

КонецЕсли;

Если Число % 2 = 0 Тогда

Возврат Ложь;

КонецЕсли;

Граница = Цел(Sqrt(Число));

Для Делитель = 3 По Граница Цикл

Если Делитель % 2 = 0 Тогда

Продолжить;

КонецЕсли;

Если Число % Делитель = 0 Тогда

Возврат Ложь;

КонецЕсли;

КонецЦикла;

Возврат Истина;

КонецФункции

Обратите внимание на крайние случаи: единица и ноль не являются простыми, двойка — единственное чётное простое число. Отрицательные числа функция также отклоняет условием Число < 2.

Решето Эратосфена для поиска всех простых чисел диапазона

Когда нужно найти не одно число, а все простые до заданной границы, перебор с проверкой каждого числа становится расточительным. Решето Эратосфена решает задачу элегантнее: создаётся массив флагов, и последовательно вычёркиваются все числа, кратные уже найденным простым.

Алгоритм: заполняем массив значениями «Истина», затем для каждого простого числа p начиная с 2 помечаем как составные все его кратные, начиная с p². Начинать именно с квадрата важно — все меньшие кратные уже вычеркнуты при обработке предыдущих простых чисел.

Функция НайтиПростыеЧисла(ВерхняяГраница) Экспорт

Результат = Новый Массив;

Если ВерхняяГраница < 2 Тогда

Возврат Результат;

КонецЕсли;

// Индекс массива соответствует числу (0 и 1 не используются)

Флаги = Новый Массив(ВерхняяГраница + 1);

Для Инд = 0 По ВерхняяГраница Цикл

Флаги[Инд] = Истина;

КонецЦикла;

Флаги[0] = Ложь;

Флаги[1] = Ложь;

ГраницаКорня = Цел(Sqrt(ВерхняяГраница));

Для Текущее = 2 По ГраницаКорня Цикл

Если Флаги[Текущее] Тогда

Кратное = Текущее * Текущее;

Пока Кратное <= ВерхняяГраница Цикл

Флаги[Кратное] = Ложь;

Кратное = Кратное + Текущее;

КонецЦикла;

КонецЕсли;

КонецЦикла;

Для Инд = 2 По ВерхняяГраница Цикл

Если Флаги[Инд] Тогда

Результат.Добавить(Инд);

КонецЕсли;

КонецЦикла;

Возврат Результат;

КонецФункции

Как вывести результат в обработке или отчёте

Полученный массив удобно вывести через таблицу значений на форме обработки. Создайте реквизит формы типа «ТаблицаЗначений» с колонкой «ПростоеЧисло», добавьте её на форму, а в команде заполнения загрузите массив из функции решета.

Пример команды формы:

&НаКлиенте

Процедура НайтиПростые(Команда)

НайтиПростыеНаСервере(ВерхняяГраница);

КонецПроцедуры

&НаСервере

Процедура НайтиПростыеНаСервере(Граница)

ТаблицаПростых.Очистить();

МассивПростых = НайтиПростыеЧисла(Граница);

Для Каждого Число Из МассивПростых Цикл

НоваяСтрока = ТаблицаПростых.Добавить();

НоваяСтрока.ПростоеЧисло = Число;

КонецЦикла;

КонецПроцедуры

Тяжёлое вычисление выполняется на сервере, клиентская процедура только инициирует вызов. Если расчёт занимает больше пары секунд, выведите индикатор длительной операции или предупреждение, чтобы пользователь не считал программу зависшей.

Порядок действий
  1. 1
    Создайте внешнюю обработку или общий модуль для функций поиска
  2. 2
    Добавьте функцию ЭтоПростоеЧисло для единичных проверок
  3. 3
    Добавьте функцию НайтиПростыеЧисла с решетом Эратосфена для диапазонов
  4. 4
    Создайте форму с полем верхней границы и таблицей результата
  5. 5
    Проверьте работу на известных данных: до 20 должно быть 8 простых чисел

Сравнение методов: когда что выбирать

Выбор алгоритма зависит от постановки задачи. Проверка одного числа делителями эффективна при единичных вызовах и не требует памяти под массив. Решето выигрывает, когда нужно много простых чисел сразу: оно находит их все за один проход вместо повторных проверок.

КритерийПроверка делителямиРешето Эратосфена
ЗадачаПроверить одно числоНайти все простые до N
ПамятьПочти не требуетМассив размером N+1
Скорость на диапазонеМедленнее при больших NЗначительно быстрее
Сложность реализацииМинимальнаяСредняя

Сравнение вариантов

Перебор делителей

Подходит для проверки отдельных чисел и малых диапазонов; не требует дополнительной памяти, но медленен на больших списках

Решето Эратосфена

Оптимально для получения всех простых чисел до границы; требует массива флагов, поэтому ограничено доступной памятью

Готовые таблицы простых чисел

Для фиксированных небольших диапазонов можно хранить список в макете или константе и не считать вовсе

Производительность и ограничения платформы

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

Следите за типом данных: при больших границах произведение Текущее * Текущее должно оставаться в допустимом диапазоне числового типа. Для практических задач в рамках типовых прикладных решений переполнение маловероятно, но при экспериментах с границами в миллиарды проверку стоит добавить.

Если поиск простых чисел — часть регламентного задания, запускайте его в фоне и сохраняйте результат в регистр сведений, чтобы не пересчитывать при каждом обращении.

Типичные ошибки при реализации

Типичные ошибки
01
Считать единицу простым числом — по определению простые числа начинаются с двойки, проверка Число < 2 обязательна
02
Перебирать делители до самого числа вместо квадратного корня — время работы растёт в разы без пользы для результата
03
В решете начинать вычеркивание кратных с 2*p вместо p*p — лишние итерации снижают производительность
04
Выходить за границу массива флагов — массив должен иметь размер ВерхняяГраница + 1, так как индексация начинается с нуля
05
Использовать вещественный результат Sqrt без приведения к целому — сравнение в цикле должно работать с целой границей

Отдельная группа ошибок связана с архитектурой: размещение вычислений в клиентской процедуре без директивы &НаСервере, отсутствие проверки введённой пользователем границы на разумные пределы, повторный пересчёт при каждом открытии формы вместо кэширования результата.

Проверка корректности результата

Проверить алгоритм просто: количество простых чисел на известных отрезках давно вычислено. До 10 их 4 (2, 3, 5, 7), до 20 — 8, до 100 — 25, до 1000 — 168. Если ваша функция возвращает эти значения, базовая логика верна.

Контрольные точки

Как проверить результат

Простые числа до 10
Норма

Список: 2, 3, 5, 7 — всего 4 числа

Тревожный признак

В списке есть 1 или 4, либо пропущена двойка

Количество простых до 100
Норма

Ровно 25 чисел, последнее — 97

Тревожный признак

Количество отличается, есть чётные числа кроме 2

Граничное значение
Норма

Сама верхняя граница включается, если она простая

Тревожный признак

Число, равное границе, теряется из-за ошибки в условии цикла

Дополнительный тест — кросс-проверка двух методов: прогоните диапазон через решето и через поэлементную проверку функцией ЭтоПростоеЧисло. Результаты должны совпасть полностью; расхождение укажет на ошибку в одном из алгоритмов.

Итог

Что важно запомнить

Для единичной проверки достаточно перебора нечётных делителей до квадратного корня. Для списка простых чисел используйте решето Эратосфена с массивом флагов. Проверяйте результат по известным контрольным значениям и не запускайте тяжёлые вычисления в интерактивном сеансе рабочей базы.

Частые вопросы

Почему единица не считается простым числом?

По определению простое число имеет ровно два различных натуральных делителя. У единицы делитель только один — она сама, поэтому она не относится ни к простым, ни к составным числам. В коде это отсекается условием Число < 2.

Можно ли найти простые числа запросом 1С без кода?

Теоретически можно построить запрос с соединением таблицы чисел самой с собой и проверкой делимости, но такой запрос будет медленным и трудночитаемым. Язык запросов не предназначен для итеративных вычислений — используйте встроенный язык.

Как ускорить решето Эратосфена в 1С?

Храните флаги только для нечётных чисел, уменьшив массив вдвое; начинайте вычеркивание с квадрата простого; не выводите промежуточные сообщения внутри цикла — каждый вызов Сообщить() заметно тормозит выполнение.

Есть ли в 1С встроенная функция проверки простоты числа?

Нет, встроенный язык платформы не содержит такой функции. Доступны только базовые математические операции, включая Sqrt для извлечения корня, поэтому алгоритм реализуется вручную — как показано в примерах выше.

Какой максимальный диапазон разумен для поиска в 1С?

Комфортная граница зависит от сервера, но на практике решето до нескольких миллионов выполняется за приемлемое время. Для больших диапазонов лучше разбивать расчёт на блоки, выполнять его в фоновом задании или выносить во внешний инструмент.

Где разместить функции поиска простых чисел в конфигурации?

Если функции нужны в нескольких местах — в общем модуле с признаком «Сервер». Для разовой задачи достаточно модуля объекта внешней обработки. Экспортируйте функции ключевым словом Экспорт, чтобы вызывать их из других модулей.