При разработке прикладных решений на платформе 1С:Предприятие часто возникает задача определения разрядности числа или подсчета общего количества содержащихся в нем цифр. Например, это требуется для валидации введенных номеров, генерации штрихкодов или форматирования документов.
Разберем основные подходы к решению этой задачи: от простого форматирования строки до математических методов, а также проанализируем важные нюансы работы с разделителями триад, отрицательными и дробными числами.
Самый простой, универсальный и надежный способ — преобразовать числовое значение в строку без лишних символов разделителей и измерить ее длину с помощью функции СтрДлина().
Рассмотрим важную особенность платформы 1С: при стандартном вызове Строка(Число) платформа автоматически разбивает число на триады, используя неразрывный пробел (код символа 160). По этой причине функция СтрЗаменить(Строка(Число), " ", "") со стандартным пробелом не удалит разделители. Чтобы получить чистую последовательность цифр без разделителей групп, необходимо использовать явный параметр форматирования ЧГ=0 (или ЧГ=).
Посмотрим на пример кода для положительного целого числа:
КоличествоЦифр = СтрДлина(Формат(Число, "ЧГ=0"));
Если число может быть отрицательным, знак минуса добавит один символ к строке. В таком случае разберем универсальный алгоритм с учетом знака и возможных дробных разделителей:
// Берем число по модулю, отключаем разделители групп и разделители дробной части
ЧислоПоМодулю = ?(Число < 0, -Число, Число);
КоличествоЦифр = СтрДлина(Формат(ЧислоПоМодулю, "ЧГ=0; ЧРД="));
Для положительных целых чисел можно применить классическую математическую формулу с использованием десятичного логарифма Log10(). Количество знаков в числе вычисляется как целая часть десятичного логарифма плюс единица.
Проанализируем ограничения данного метода:
Log10() работает с числами двойной точности с плавающей точкой (около 15–17 значащих цифр). Если разрядность числа в 1С превышает 15 знаков (тип Число в 1С поддерживает до 38 знаков), из-за погрешности вычислений результат может быть неточным.Рассмотрим реализацию безопасного вычисления через тернарный оператор с обработкой нуля и отрицательных значений:
Если Число = 0 Тогда
КоличествоЦифр = 1;
Иначе
ПоложительноеЧисло = ?(Число < 0, -Число, Число);
КоличествоЦифр = Цел(Log10(ПоложительноеЧисло)) + 1;
КонецЕсли;
Если исходная строка может содержать посторонние символы или требуется явно проверить каждый знак на принадлежность диапазону цифр от "0" до "9", разберем циклический алгоритм обхода строки.
Посмотрим на пример функции подсчета цифр:
СтрокаПроверки = Строка(Число);
КоличествоЦифр = 0;
Для Индекс = 1 По СтрДлина(СтрокаПроверки) Цикл
ТекущийСимвол = Сред(СтрокаПроверки, Индекс, 1);
Если ТекущийСимвол >= "0" И ТекущийСимвол <= "9" Тогда
КоличествоЦифр = КоличествоЦифр + 1;
КонецЕсли;
КонецЦикла;
Сообщить("Количество цифр: " + КоличествоЦифр);
Если требуется обработать целое число исключительно арифметическими операциями без преобразования в тип Строка и без использования логарифмов, разберем по шагам алгоритм циклического деления на 10:
КоличествоЦифр = 0;
ВременноеЧисло = ?(Число < 0, -Число, Число);
Если ВременноеЧисло = 0 Тогда
КоличествоЦифр = 1;
Иначе
Пока ВременноеЧисло >= 1 Цикл
ВременноеЧисло = Цел(ВременноеЧисло / 10);
КоличествоЦифр = КоличествоЦифр + 1;
КонецЦикла;
КонецЕсли;
СтрДлина(Формат(?(Число < 0, -Число, Число), "ЧГ=0; ЧРД=")).ЧГ=0 в формате предпочтительнее ручной замены символов.Log10() отлично подходит для быстрой оценки целых положительных чисел разрядностью до 15 знаков.