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