Всем доброго дня, уважаемые коллеги! У меня вот какой вопрос. Где описаны правила деления чисел в 1С в части разрядности числа?
Например, делим 295/7186387.12 получаем число с количеством знаков 29, делим 295.01/7186387.12 - получаем количество 38; делим 295/7186387 - количество 28 знаков. Что это за магия? В запросах понятно, там есть даже описание 1С-кое, а вот с указанными примерами - все обыскал, не могу найти ответа.
Заранее спасибо всем откликнувшимся))
1. А зачем Вам больше 20 знаков после запятой? 1/10^20 - это очень мало, особенно если перевести в деньги.
2. 1С вряд ли придумала то, как делить числа. В компьютерном мире принято работать с числами с плавающей точкой одинарной и двойной точности, представленных в виде мантиссы и экспоненты. Их разрядность ограничена и не может представить любое число, иначе 1С никогда бы не закончила деление 1/3.
(1) где-то в зазеркалье видел описание какой длинны могут быть числа.
Если у вас переменная, то длина будет зависеть от значений, но максимальная точность вам в (3) указали.
А если реквизит, то значение будет приведено к его точности. Считай применили не явно округление.
Иногда тут пишут статьи про такую магию кода.
(1) Подозреваю, что деление в 1С реализовано не на аппаратном уровне, а программно. Основной вопрос, почему 295/7186387 - количество 28 знаков, а не 38, ведь там есть что выводить. Скорее всего, итоговая длина зависит от получаемой погрешности приближения. В случае с 295/7186387 допустимая погрешность была достигнута в 28 знаков. Видно в каком месте отсекаются "копейки", если посмотреть на результат:
295/7186387 = 0.000041049834917045241231790049714829 — 38 символов
295/7186387 = 0.00004104983491704524123179 — 28 символов
Допустимая погрешность, видимо, также определяется исходя из точности входящих данных.
почему деля 150,2/7878 получим одно количество знаков (38), а деля 150/7878 - получим 28?
результат будет зависеть от делимого и делителя.
(0)
Для размышления, попробуйте такую формулу:
295.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001/7186387.12
1. А зачем Вам больше 20 знаков после запятой? 1/10^20 - это очень мало, особенно если перевести в деньги.
2. 1С вряд ли придумала то, как делить числа. В компьютерном мире принято работать с числами с плавающей точкой одинарной и двойной точности, представленных в виде мантиссы и экспоненты. Их разрядность ограничена и не может представить любое число, иначе 1С никогда бы не закончила деление 1/3.
(2) Жаль, конечно, что я не программист и не математик по образованию. Но то, что вы говорите, больше похоже на правду, имхо. Конечно, прямого ответа я не нашел, но направление исследований понятно. Спасибо!
И такое может быть. Фактически, фиксированная точка - это не очень хорошо в части памяти, т.к. выделено какое-то количество байт на целую и не целую часть. А может быть 1С эту память динамически выделяет, добавляя байты для сверхмалых и сверхбольших чисел, или сверхбольших чисел с сверхбольшой частью после запятой. В итоге это все малополезно, при этом ведет к замедлению вычислений и увеличению количества потребляемой памяти. Та же функция степени в 1С по всей видимости и из-за этого тоже работает очень медленно, хотя показывает более точные числа при большом количестве итераций.
Максимально допустимая разрядность числа – 32 знака.
в описании типа Число написано:
Числовым типом может быть представлено любое десятичное число. Над данными числового типа определены основные арифметические операции: сложение, вычитание, умножение и деление. Максимально допустимая разрядность числа 38 знаков.
я так понимаю
1) важна исходная точность, поэтому первый и второй пример дают разную точность
2) 38 знаков - максимум
3) ваши примеры очень неудачные, т.к. число получается маленькое...
4) я стараюсь делать так, что бы деление было последним действием
если сильно заморочиться, можно хранить числа в строке в виде дроби,
и результат получать через Выполнить()
(4)Спасибо, посмотрю. По поводу маленьких чисел в результате... Тут не результат важен, а именно количество знаков. Да, их максимально может быть 38 (учитывая , и 0 в приведенном примере), но почему получается разное количество знаков - я не понимаю)) Pow посмотрю.
По итогам исследований - https://mista.ru/topic/892985 (1С 8.3.222283)
И так при делении, Если ПЕРВЫЙ аргумент целый - 27 знаков
с 1 знака после запятой - 36 знаков
с 11 знака после запятой - 45 знаков
с 19 знака после запятой - 54 знака
с 28 знака после запятой - 63 знака
с 37 знака после запятой - 72 знака
Если последние нули, то кажется округление делается на меньшее количество знаков.
То есть реализация Числа в 1С то это BigDecimal (Java) или bc Math (PHP)