Skip to main content

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

Для всех арифметических функций, тип результата вычисляется, как минимальный числовой тип, который может вместить результат, если такой тип есть. Минимум берётся одновременно по числу бит, знаковости и «плавучести». Если бит не хватает, то берётся тип максимальной битности.

Пример:

SELECT toTypeName(0), toTypeName(0 + 0), toTypeName(0 + 0 + 0), toTypeName(0 + 0 + 0 + 0)
┌─toTypeName(0)─┬─toTypeName(plus(0, 0))─┬─toTypeName(plus(plus(0, 0), 0))─┬─toTypeName(plus(plus(plus(0, 0), 0), 0))─┐
│ UInt8 │ UInt16 │ UInt32 │ UInt64 │
└───────────────┴────────────────────────┴─────────────────────────────────┴──────────────────────────────────────────┘

Арифметические функции работают для любой пары типов из UInt8, UInt16, UInt32, UInt64, Int8, Int16, Int32, Int64, Float32, Float64.

Переполнение производится также, как в C++.

plus(a, b), оператор a + b

Вычисляет сумму чисел. Также можно складывать целые числа с датой и датой-с-временем. В случае даты, прибавление целого числа означает прибавление соответствующего количества дней. В случае даты-с-временем - прибавление соответствующего количества секунд.

minus(a, b), оператор a - b

Вычисляет разность чисел. Результат всегда имеет знаковый тип.

Также можно вычитать целые числа из даты и даты-с-временем. Смысл аналогичен - смотрите выше для plus.

multiply(a, b), оператор a * b

Вычисляет произведение чисел.

divide(a, b), оператор a / b

Вычисляет частное чисел. Тип результата всегда является типом с плавающей запятой. То есть, деление не целочисленное. Для целочисленного деления, используйте функцию intDiv. При делении на ноль получится inf, -inf или nan.

intDiv(a, b)

Вычисляет частное чисел. Деление целочисленное, с округлением вниз (по абсолютному значению). При делении на ноль или при делении минимального отрицательного числа на минус единицу, кидается исключение.

intDivOrZero(a, b)

Отличается от intDiv тем, что при делении на ноль или при делении минимального отрицательного числа на минус единицу, возвращается ноль.

modulo(a, b), оператор a % b

Вычисляет остаток от деления. Тип результата - целое число, если оба аргумента - целые числа. Если один из аргументов является числом с плавающей точкой, результатом будет число с плавающей точкой. Берётся остаток в том же смысле, как это делается в C++. По факту, для отрицательных чисел, используется truncated division. При делении на ноль или при делении минимального отрицательного числа на минус единицу, кидается исключение.

moduloOrZero(a, b)

В отличие от modulo, возвращает ноль при делении на ноль.

negate(a), оператор -a

Вычисляет число, обратное по знаку. Результат всегда имеет знаковый тип.

abs(a)

Вычисляет абсолютное значение для числа a. То есть, если a \< 0, то возвращает -a. Для беззнаковых типов ничего не делает. Для чисел типа целых со знаком, возвращает число беззнакового типа.

gcd(a, b)

Вычисляет наибольший общий делитель чисел. При делении на ноль или при делении минимального отрицательного числа на минус единицу, кидается исключение.

lcm(a, b)

Вычисляет наименьшее общее кратное чисел. При делении на ноль или при делении минимального отрицательного числа на минус единицу, кидается исключение.

max2

Сравнивает два числа и возвращает максимум. Возвращаемое значение приводится к типу Float64.

Синтаксис

max2(value1, value2)

Аргументы

Возвращаемое значение

  • Максимальное значение среди двух чисел.

Тип: Float.

Пример

Запрос:

SELECT max2(-1, 2);

Результат:

┌─max2(-1, 2)─┐
│ 2 │
└─────────────┘

min2

Сравнивает два числа и возвращает минимум. Возвращаемое значение приводится к типу Float64.

Синтаксис

min2(value1, value2)

Аргументы

Возвращаемое значение

  • Минимальное значение среди двух чисел.

Тип: Float.

Пример

Запрос:

SELECT min2(-1, 2);

Результат:

┌─min2(-1, 2)─┐
│ -1 │
└─────────────┘

multiplyDecimal(a, b[, result_scale])

Совершает умножение двух Decimal. Результат будет иметь тип Decimal256. Scale (размер дробной части) результат можно явно задать аргументом result_scale (целочисленная константа из интервала [0, 76]). Если этот аргумент не задан, то scale результата будет равен наибольшему из scale обоих аргументов.

Синтаксис

multiplyDecimal(a, b[, result_scale])
note

Эта функция работает гораздо медленнее обычной multiply. В случае, если нет необходимости иметь фиксированную точность и/или нужны быстрые вычисления, следует использовать multiply.

Аргументы

  • a — Первый сомножитель/делимое: Decimal.
  • b — Второй сомножитель/делитель: Decimal.
  • result_scale — Scale результата: Int/UInt.

Возвращаемое значение

  • Результат умножения с заданным scale.

Тип: Decimal256.

Примеры

SELECT multiplyDecimal(toDecimal256(-12, 0), toDecimal32(-2.1, 1), 1);
┌─multiplyDecimal(toDecimal256(-12, 0), toDecimal32(-2.1, 1), 1)─┐
│ 25.2 │
└────────────────────────────────────────────────────────────────┘

Отличие от стандартных функций

SELECT toDecimal64(-12.647, 3) * toDecimal32(2.1239, 4);
SELECT toDecimal64(-12.647, 3) as a, toDecimal32(2.1239, 4) as b, multiplyDecimal(a, b);
┌─multiply(toDecimal64(-12.647, 3), toDecimal32(2.1239, 4))─┐
│ -26.8609633 │
└───────────────────────────────────────────────────────────┘
┌─multiplyDecimal(toDecimal64(-12.647, 3), toDecimal32(2.1239, 4))─┐
│ -26.8609 │
└──────────────────────────────────────────────────────────────────┘
SELECT
toDecimal64(-12.647987876, 9) AS a,
toDecimal64(123.967645643, 9) AS b,
multiplyDecimal(a, b);

SELECT
toDecimal64(-12.647987876, 9) AS a,
toDecimal64(123.967645643, 9) AS b,
a * b;
┌─────────────a─┬─────────────b─┬─multiplyDecimal(toDecimal64(-12.647987876, 9), toDecimal64(123.967645643, 9))─┐
│ -12.647987876 │ 123.967645643 │ -1567.941279108 │
└───────────────┴───────────────┴───────────────────────────────────────────────────────────────────────────────┘

Received exception from server (version 22.11.1):
Code: 407. DB::Exception: Received from localhost:9000. DB::Exception: Decimal math overflow: While processing toDecimal64(-12.647987876, 9) AS a, toDecimal64(123.967645643, 9) AS b, a * b. (DECIMAL_OVERFLOW)

divideDecimal(a, b[, result_scale])

Совершает деление двух Decimal. Результат будет иметь тип Decimal256. Scale (размер дробной части) результат можно явно задать аргументом result_scale (целочисленная константа из интервала [0, 76]). Если этот аргумент не задан, то scale результата будет равен наибольшему из scale обоих аргументов.

Синтаксис

divideDecimal(a, b[, result_scale])
note

Эта функция работает гораздо медленнее обычной divide. В случае, если нет необходимости иметь фиксированную точность и/или нужны быстрые вычисления, следует использовать divide.

Аргументы

  • a — Первый сомножитель/делимое: Decimal.
  • b — Второй сомножитель/делитель: Decimal.
  • result_scale — Scale результата: Int/UInt.

Возвращаемое значение

  • Результат деления с заданным scale.

Тип: Decimal256.

Примеры

SELECT divideDecimal(toDecimal256(-12, 0), toDecimal32(2.1, 1), 10);
┌─divideDecimal(toDecimal256(-12, 0), toDecimal32(2.1, 1), 10)─┐
│ -5.7142857142 │
└──────────────────────────────────────────────────────────────┘

Отличие от стандартных функций

SELECT toDecimal64(-12, 1) / toDecimal32(2.1, 1);
SELECT toDecimal64(-12, 1) as a, toDecimal32(2.1, 1) as b, divideDecimal(a, b, 1), divideDecimal(a, b, 5);
┌─divide(toDecimal64(-12, 1), toDecimal32(2.1, 1))─┐
│ -5.7 │
└──────────────────────────────────────────────────┘

┌───a─┬───b─┬─divideDecimal(toDecimal64(-12, 1), toDecimal32(2.1, 1), 1)─┬─divideDecimal(toDecimal64(-12, 1), toDecimal32(2.1, 1), 5)─┐
│ -12 │ 2.1 │ -5.7 │ -5.71428 │
└─────┴─────┴────────────────────────────────────────────────────────────┴────────────────────────────────────────────────────────────┘
SELECT toDecimal64(-12, 0) / toDecimal32(2.1, 1);
SELECT toDecimal64(-12, 0) as a, toDecimal32(2.1, 1) as b, divideDecimal(a, b, 1), divideDecimal(a, b, 5);
DB::Exception: Decimal result's scale is less than argument's one: While processing toDecimal64(-12, 0) / toDecimal32(2.1, 1). (ARGUMENT_OUT_OF_BOUND)

┌───a─┬───b─┬─divideDecimal(toDecimal64(-12, 0), toDecimal32(2.1, 1), 1)─┬─divideDecimal(toDecimal64(-12, 0), toDecimal32(2.1, 1), 5)─┐
│ -12 │ 2.1 │ -5.7 │ -5.71428 │
└─────┴─────┴────────────────────────────────────────────────────────────┴────────────────────────────────────────────────────────────┘