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

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

Арифметические функции работают с любыми двумя операндами типов 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 (оператор)

divideOrNull

Как divide, но возвращает null, когда делитель равен нулю.

Синтаксис

intDiv

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

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

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

Синтаксис

Пример

Запрос:

intDivOrZero

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

Синтаксис

intDivOrNull

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

Синтаксис

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, но возвращает ноль, когда делитель равен нулю.

Синтаксис

moduloOrNull

Как modulo, но возвращает null, когда делитель равен нулю.

Синтаксис

positiveModulo(a, b)

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

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

Синтаксис

Псевдоним:

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

Пример

Запрос:

Результат:

positiveModuloOrNull(a, b)

Как positiveModulo, но возвращает null, когда делитель равен нулю.

Синтаксис

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

Обменяет байты целого числа, т.е. изменяет его endianness.

Синтаксис

Пример

Результат:

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

  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: