Перейти к основному содержимому
Перейти к основному содержимому

Арифметические функции

Арифметические функции работают для любых двух операндов типов UInt8, UInt16, UInt32, UInt64, Int8, Int16, Int32, Int64, Float32 или Float64.

Перед выполнением операции оба операнда приводятся к типу результата. Тип результата определяется следующим образом (если не указано иное в документации функции ниже):

  • Если оба операнда имеют ширину до 32 бит, размер типа результата будет равен размеру следующего большего типа, следующего за большим из двух операндов (повышение размера целого числа). Например, UInt8 + UInt16 = UInt32 или Float32 * Float32 = Float64.
  • Если один из операндов имеет 64 или более бит, размер типа результата будет таким же, как и больший из двух операндов. Например, UInt32 + UInt128 = UInt128 или Float32 * Float64 = Float64.
  • Если один из операндов знаковый, тип результата также будет знаковым, иначе он будет беззнаковым. Например, UInt32 * Int32 = Int64.

Эти правила гарантируют, что тип результата будет наименьшим типом, который может представлять все возможные результаты. Хотя это создает риск переполнения вокруг границы диапазона значений, это гарантирует, что вычисления выполняются быстро, используя максимальную ширину родного целого числа 64 бита. Это поведение также гарантирует совместимость со многими другими базами данных, которые предоставляют 64-битные целые числа (BIGINT) в качестве наибольшего типа целого числа.

Пример:

Переполнения происходят так же, как в C++.

plus

Вычисляет сумму двух значений a и b.

Синтаксис

Можно добавить целое число и дату или дату с временем. Первоначальная операция увеличивает количество дней в дате, последняя операция увеличивает количество секунд в дате с временем.

Псевдоним: a + b (оператор)

minus

Вычисляет разность двух значений a и b. Результат всегда знаковый.

Аналогично plus, можно вычесть целое число из даты или даты с временем.

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

Синтаксис

Псевдоним: a - b (оператор)

multiply

Вычисляет произведение двух значений a и b.

Синтаксис

Псевдоним: a * b (оператор)

divide

Вычисляет частное двух значений a и b. Тип результата всегда Float64. Целочисленное деление предоставляется функцией intDiv.

Деление на 0 возвращает inf, -inf или nan.

Синтаксис

Псевдоним: a / b (оператор)

intDiv

Выполняет целочисленное деление двух значений a на b, т.е. вычисляет частное, округленное вниз до следующего меньшего целого.

Результат имеет такую же ширину, как и делимое (первый параметр).

Существует исключение, выдается ошибка при делении на ноль, если частное не помещается в диапазон делимого или при делении минимального отрицательного числа на минус один.

Синтаксис

Пример

Запрос:

intDivOrZero

То же самое, что и intDiv, но возвращает ноль при делении на ноль или при делении минимального отрицательного числа на минус один.

Синтаксис

isFinite

Возвращает 1, если аргумент Float32 или Float64 не бесконечен и не NaN, в противном случае эта функция возвращает 0.

Синтаксис

isInfinite

Возвращает 1, если аргумент Float32 или Float64 бесконечен, в противном случае эта функция возвращает 0. Обратите внимание, что 0 возвращается для NaN.

Синтаксис

ifNotFinite

Проверяет, является ли значение с плавающей запятой конечным.

Синтаксис

Аргументы

  • x — Значение для проверки на бесконечность. Float*.
  • y — Резервное значение. Float*.

Возвращаемое значение

  • x, если x конечен.
  • y, если x не конечен.

Пример

Запрос:

SELECT 1/0 as infimum, ifNotFinite(infimum,42)

Результат:

┌─infimum─┬─ifNotFinite(divide(1, 0), 42)─┐ │ inf │ 42 │ └─────────┴───────────────────────────────┘

Вы можете получить аналогичный результат, используя тернарный оператор: isFinite(x) ? x : y.

isNaN

Возвращает 1, если аргумент Float32 и Float64 является NaN, в противном случае эта функция возвращает 0.

Синтаксис

modulo

Вычисляет остаток от деления двух значений a на b.

Тип результата является целым числом, если оба входных значения являются целыми. Если одно из входных значений является числом с плавающей запятой, тип результата будет Float64.

Остаток вычисляется так же, как в C++. Для отрицательных чисел используется усеченное деление.

При делении на ноль или при делении минимального отрицательного числа на минус один возникает исключение.

Синтаксис

Псевдоним: a % b (оператор)

moduloOrZero

Как modulo, но возвращает ноль при делении на ноль.

Синтаксис

positiveModulo(a, b)

Как modulo, но всегда возвращает неотрицательное число.

Эта функция работает на 4-5 раз медленнее, чем modulo.

Синтаксис

Псевдонимы:

  • positive_modulo(a, b)
  • pmod(a, b)

Пример

Запрос:

Результат:

negate

Отрицает значение a. Результат всегда знаковый.

Синтаксис

Псевдоним: -a

abs

Вычисляет абсолютное значение a. Не имеет эффекта, если a является беззнаковым типом. Если a является знаковым типом, он возвращает беззнаковое число.

Синтаксис

gcd

Возвращает наибольший общий делитель двух значений a и b.

При делении на ноль или при делении минимального отрицательного числа на минус один возникает исключение.

Синтаксис

lcm(a, b)

Возвращает наименьшее общее кратное двух значений a и b.

При делении на ноль или при делении минимального отрицательного числа на минус один возникает исключение.

Синтаксис

max2

Возвращает большее из двух значений a и b. Возвращаемое значение имеет тип Float64.

Синтаксис

Пример

Запрос:

Результат:

min2

Возвращает меньшее из двух значений a и b. Возвращаемое значение имеет тип Float64.

Синтаксис

Пример

Запрос:

Результат:

multiplyDecimal

Умножает два десятичных числа a и b. Результат будет иметь тип Decimal256.

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

Эта функция работает значительно медленнее, чем обычное multiply. Если нет контроля над точностью результата или требуется быстрое вычисление, подумайте о том, чтобы использовать multiply.

Синтаксис

Аргументы

  • a — Первое значение. Decimal.
  • b — Второе значение. Decimal.
  • result_scale — Шкала результата. Int/UInt.

Возвращаемое значение

  • Результат умножения с заданной шкалой. Decimal256.

Пример

Отличия по сравнению с обычным умножением:

Результат:

Результат:

divideDecimal

Делит два десятичных числа a и b. Результат будет иметь тип Decimal256.

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

Эта функция работает значительно медленнее, чем обычное divide. Если нет контроля над точностью результата или требуется быстрое вычисление, подумайте о том, чтобы использовать divide.

Синтаксис

Аргументы

  • a — Первое значение: Decimal.
  • b — Второе значение: Decimal.
  • result_scale — Шкала результата: Int/UInt.

Возвращаемое значение

  • Результат деления с заданной шкалой. Decimal256.

Пример

Отличия по сравнению с обычным делением:

Результат:

Результат:

byteSwap

Обращает байты целого числа, т.е. изменяет его порядок байт.

Синтаксис

Пример

Результат:

Приведенный выше пример можно разобрать следующим образом:

  1. Преобразуйте десятичное целое число в его эквивалентный шестнадцатеричный формат в формате big-endian, т.е. 3351772109 -> C7 C7 FB CD (4 байта)
  2. Обратите байты, т.е. C7 C7 FB CD -> CD FB C7 C7
  3. Преобразуйте результат обратно в целое число, предполагая формат big-endian, т.е. CD FB C7 C7 -> 3455829959

Один из случаев использования этой функции — обращение IPv4: