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