跳到主要内容
跳到主要内容

算术函数

算术函数适用于任何两个类型为 UInt8UInt16UInt32UInt64Int8Int16Int32Int64Float32Float64 的操作数。

在执行操作之前,两个操作数都会被转换为结果类型。结果类型的确定如下(除非在下面的函数文档中另有说明):

  • 如果两个操作数的位宽都不超过 32 位,结果类型的大小将是两个操作数中较大者的下一个更大类型的大小(整数大小推广)。例如,UInt8 + UInt16 = UInt32Float32 * Float32 = Float64
  • 如果其中一个操作数有 64 位或更多,则结果类型的大小将与两个操作数中较大者的大小相同。例如,UInt32 + UInt128 = UInt128Float32 * Float64 = Float64
  • 如果其中一个操作数是带符号的,则结果类型也将是带符号的,否则它将是无符号的。例如,UInt32 * Int32 = Int64

这些规则确保结果类型将是可以表示所有可能结果的最小类型。虽然这在值范围边界附近引入了溢出的风险,但它确保使用 64 位的最大本机整数宽度快速执行计算。这种行为也保证了与许多其他提供 64 位整数(BIGINT)作为最大整数类型的数据库的兼容性。

示例:

溢出产生的方式与 C++ 中相同。

plus

计算两个值 ab 的和。

语法

可以将整数与日期或带时间的日期相加。前一种操作会增加日期中的天数,而后一种操作会增加带时间日期中的秒数。

别名:a + b(操作符)

minus

计算两个值 ab 的差。结果始终为有符号类型。

plus 类似,可以从日期或带时间的日期中减去一个整数。

此外,支持带时间的日期之间的减法,得到它们之间的时间差。

语法

别名:a - b(操作符)

multiply

计算两个值 ab 的乘积。

语法

别名:a * b(操作符)

divide

计算两个值 ab 的商。结果类型始终为 Float64。整数除法使用 intDiv 函数提供。

除以 0 返回 inf-infnan

语法

别名:a / b(操作符)

intDiv

对两个值 ab 进行整数除法,即计算商并向下取整到下一个较小的整数。

结果的宽度与被除数(第一个参数)相同。

在除以零、商不适合被除数范围时,或在将最小负数除以负一时会抛出异常。

语法

示例

查询:

intDivOrZero

intDiv 相同,但在除以零或将最小负数除以负一时返回零。

语法

isFinite

如果 Float32 或 Float64 参数不是无穷大且不是 NaN,则返回 1;否则此函数返回 0。

语法

isInfinite

如果 Float32 或 Float64 参数是无穷大,则返回 1;否则此函数返回 0。请注意,对于 NaN 返回 0。

语法

ifNotFinite

检查浮点值是否是有限的。

语法

参数

  • x — 要检查是否为无穷大的值。Float*
  • y — 回退值。Float*

返回值

  • 如果 x 是有限的,则返回 x
  • 如果 x 不是有限的,则返回 y

示例

查询:

SELECT 1/0 as infimum, ifNotFinite(infimum,42)

结果:

┌─infimum─┬─ifNotFinite(divide(1, 0), 42)─┐ │ inf │ 42 │ └─────────┴───────────────────────────────┘

您可以使用 三元操作符 获得类似的结果:isFinite(x) ? x : y

isNaN

如果 Float32 和 Float64 参数是 NaN,则返回 1;否则此函数返回 0。

语法

modulo

计算两个值 ab 除法的余数。

如果两个输入都是整数,则结果类型为整数。如果其中一个输入是浮点数,则结果类型为 Float64

余数的计算方式与 C++ 中相同。对于负数使用截断除法。

在除以零或将最小负数除以负一时会抛出异常。

语法

别名:a % b(操作符)

moduloOrZero

modulo 相似,但在除数为零时返回零。

语法

positiveModulo(a, b)

modulo 相似,但始终返回非负数。

此函数的速度比 modulo 慢 4-5 倍。

语法

别名:

  • positive_modulo(a, b)
  • pmod(a, b)

示例

查询:

结果:

negate

对值 a 取反。结果始终为有符号类型。

语法

别名:-a

abs

计算 a 的绝对值。如果 a 是无符号类型,则没有影响。如果 a 是带符号类型,则返回一个无符号数。

语法

gcd

返回两个值 ab 的最大公约数。

在除以零或将最小负数除以负一时会抛出异常。

语法

lcm(a, b)

返回两个值 ab 的最小公倍数。

在除以零或将最小负数除以负一时会抛出异常。

语法

max2

返回两个值 ab 中较大的一个。返回值类型为 Float64

语法

示例

查询:

结果:

min2

返回两个值 ab 中较小的一个。返回值类型为 Float64

语法

示例

查询:

结果:

multiplyDecimal

将两个十进制数 ab 相乘。结果值类型为 Decimal256

结果的规模可以通过 result_scale 显式指定。如果未指定 result_scale,则假定为输入值的最大规模。

此函数的执行速度明显慢于普通的 multiply。如果不需要控制结果精度和/或需要快速计算,建议使用 multiply

语法

参数

  • a — 第一个值。Decimal
  • b — 第二个值。Decimal
  • result_scale — 结果的规模。Int/UInt

返回值

  • 带有给定规模的乘法结果。Decimal256

示例

与常规乘法的比较:

结果:

结果:

divideDecimal

将两个十进制数 ab 相除。结果值类型为 Decimal256

结果的规模可以通过 result_scale 显式指定。如果未指定 result_scale,则假定为输入值的最大规模。

此函数的执行速度明显慢于普通的 divide。如果不需要控制结果精度和/或需要快速计算,建议使用 divide

语法

参数

  • a — 第一个值:Decimal
  • b — 第二个值:Decimal
  • result_scale — 结果的规模:Int/UInt

返回值

  • 带有给定规模的除法结果。Decimal256

示例

与常规除法的比较:

结果:

结果:

byteSwap

反转一个整数的字节,即更改其 字节序

语法

示例

结果:

以上示例的计算过程如下:

  1. 将十进制整数转换为其在大端格式下的等效十六进制格式,即 3351772109 -> C7 C7 FB CD (4 字节)
  2. 反转字节,即 C7 C7 FB CD -> CD FB C7 C7
  3. 将结果重新转换为假设为大端的整数,即 CD FB C7 C7 -> 3455829959

此函数的一个用例是反转 IPv4: