Арифметические функции
Арифметические функции работают с любыми двумя операндами типов 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
, если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.
Синтаксис
Пример
Результат:
Приведенный выше пример можно рассмотреть следующим образом:
- Преобразовать целое число в десятичной системе счисления в эквивалентный шестнадцатеричный формат в формате большого порядка, т.е. 3351772109 -> C7 C7 FB CD (4 байта)
- Перевернуть байты, т.е. C7 C7 FB CD -> CD FB C7 C7
- Преобразовать результат обратно в целое число, предполагая большой порядок, т.е. CD FB C7 C7 -> 3455829959
Одним из применений этой функции является реверсирование IPv4: