Перейти к содержанию
#std535

Округление результатов арифметических операций в запросах

1.

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

Неправильно

0.02 / 28346 * 9287492

Правильно

0.02 * 9287492 / 28346
2.

При арифметических операциях в запросах платформа обычно поддерживает точность до 8 знаков после запятой. Но из-за особенностей разных СУБД реальная точность может отличаться.

Подробнее: Разрядность результатов выражений и агрегатных функций в языке запросов.

Если на разных СУБД получается разная точность в операциях:

  • деления;
  • СРЕДНЕЕ;
  • умножения (когда у каждого множителя может быть дробная часть),

рекомендуется явно задавать разрядность оператором:

ВЫРАЗИТЬ(... КАК Число(m, n))

ВЫРАЗИТЬ применяйте к операндам, если на какой-то СУБД точность недостаточна.

ВЫБРАТЬ
    ВЫРАЗИТЬ(Таблица.Множитель * Таблица.Числитель КАК Число(25,10))
        / ВЫРАЗИТЬ(Таблица.Знаменатель КАК Число(15,10)) КАК Результат
ИЗ Таблица КАК Таблица

Разрядность операндов задавайте минимально достаточной. Избыточно большая разрядность может ухудшить точность последующих вычислений и снизить скорость выполнения.

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

ВЫРАЗИТЬ применяйте к результату, если точность на всех СУБД достаточна, но отличается.

Общую разрядность результата также задавайте минимально достаточной. Например, если знаменатель не может быть меньше 0.00001, для результата достаточно 20 разрядов целой части. При 10 знаках после запятой используйте Число(30,10).

ВЫБРАТЬ
    ВЫРАЗИТЬ(Таблица.Множитель * Таблица.Числитель / Таблица.Знаменатель КАК Число(30,10)) КАК Результат
ИЗ Таблица КАК Таблица

В ряде случаев целесообразно приводить и операнды, и результат:

ВЫБРАТЬ
    ВЫРАЗИТЬ(
        ВЫРАЗИТЬ(Таблица.Множитель * Таблица.Числитель КАК Число(25,10))
            / ВЫРАЗИТЬ(Таблица.Знаменатель КАК Число(15,10))
        КАК Число(30,10)
    ) КАК Результат
ИЗ Таблица КАК Таблица
Источники