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

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

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

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

Синтаксис

Пример

Результат:

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

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

Одним из применений этой функции является реверсирование IPv4: