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

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

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