算术运算符¶
算术运算符用于从一个或多个输入表达式生成数值输出。
输入表达式必须为数值(定点或浮点),但以下情况除外:
一元运算符
+
可以采用数字字符串,但这会导致字符串隐式转换为其相应的数值。二进制运算符
-
可应用于 DATE 表达式。
本主题内容:
算术运算符列表¶
运算符 |
语法 |
描述 |
---|---|---|
|
|
返回 |
|
|
添加两个数值表达式( |
|
|
否定输入数值表达式。 |
|
|
从一个数值表达式 ( |
|
|
从一个日期表达式 ( |
|
|
将两个数值表达式( |
|
|
将一个数值表达式 ( |
|
|
计算每个 |
算术运算的小数位数和精度¶
算术运算输出的 小数位数 和 精度 取决于输入的小数位数和精度。
本部分介绍 Snowflake 用于在各种算术运算(乘法、除法等)生成的数值输出中保留小数位数和精度的计算。本部分使用以下说明:
- 前导数字:
数值中小数点左侧的位数 (
L
)。- 小数位数:
数值中小数点右侧的位数 (
S
)。- 精度:
数值中的位总数 (
P
),以其前导数字和小数位数之和来计算(即P = L + S
)。请注意,Snowflake 中的精度始终限制为 38。另外:
定点数据类型(NUMBER、DECIMAL 等)使用精度和小数位数。例如,对于 DECIMAL (8、2)数据类型,精度为 8,小数位数为 2,前导数字为 6。
浮点数据类型(FLOAT、DOUBLE、REAL 等)使用 8 字节双精度。
对于输出,请注意这些是最大位数;任何给定输出的实际位数可能更少。
乘法¶
执行乘法时:
输出中的前导位数是两个输入中前导位数的总和。
Snowflake 通过在两个输入的小数位数中添加位数(最大阈值为 12 位)来最小化潜在的溢出(由于链式乘法),除非任一输入的小数位数大于 12,在这种情况下,较大的输入小数位数用作输出小数位数。
换言之,假设使用两个输入(L1.S1
和 L2.S2
)进行乘法运算,输出中的最大位数计算如下:
- 前导数字:
L = L1 + L2
- 小数位数:
S = min(S1 + S2, max(S1, S2, 12))
- 精度:
P = L + S
备注
Snowflake 对数值执行整型乘法运算,因此中间结果可能会导致一些溢出;但是,最终输出不会溢出。
示例¶
select 10.01 n1, 1.1 n2, n1 * n2;
+-------+-----+---------+
| N1 | N2 | N1 * N2 |
|-------+-----+---------|
| 10.01 | 1.1 | 11.011 |
+-------+-----+---------+
select 10.001 n1, .001 n2, n1 * n2;
+--------+-------+----------+
| I1 | I2 | I1 * I2 |
|--------+-------+----------|
| 10.001 | 0.001 | 0.010001 |
+--------+-------+----------+
select .1 n1, .0000000000001 n2, n1 * n2;
+-----+-----------------+-----------------+
| N1 | N2 | N1 * N2 |
|-----+-----------------+-----------------|
| 0.1 | 0.0000000000001 | 0.0000000000000 |
+-----+-----------------+-----------------+
除法¶
执行除法时:
输出的前导数字是分子的前导数字和分母的小数位数的总和。
Snowflake 通过向分子的小数位数添加 6 位数字(最大阈值为 12 位)来最大程度地减少输出中的潜在溢出(由于链式除法)和小数位数损失,除非分子的小数位数大于 12,在这种情况下,分子的小数位数用作输出的小数位数。
换言之,假设使用分子 L1.S1
和分母 L2.S2
进行除法运算,输出中的最大位数计算如下:
- 前导数字:
L = L1 + S2
- 小数位数:
S = max(S1, min(S1 + 6, 12))
- 精度:
P = L + S
如果除法运算的结果超过输出小数位数,则 Snowflake 将对输出进行舍入(而不是截断输出)。
备注
与乘法类似,中间除法结果可能会导致一些溢出;但是,最终输出不会溢出。
示例¶
select 2 n1, 7 n2, n1 / n2;
+----+----+----------+
| N1 | N2 | N1 / N2 |
|----+----+----------|
| 2 | 7 | 0.285714 |
+----+----+----------+
select 10.1 n1, 2.1 n2, n1 / n2;
+------+-----+-----------+
| N1 | N2 | N1 / N2 |
|------+-----+-----------|
| 10.1 | 2.1 | 4.8095238 |
+------+-----+-----------+
select 10.001 n1, .001 n2, n1 / n2;
+--------+-------+-----------------+
| N1 | N2 | N1 / N2 |
|--------+-------+-----------------|
| 10.001 | 0.001 | 10001.000000000 |
+--------+-------+-----------------+
select .1 n1, .0000000000001 n2, n1 / n2;
+-----+-----------------+-----------------------+
| N1 | N2 | N1 / N2 |
|-----+-----------------+-----------------------|
| 0.1 | 0.0000000000001 | 1000000000000.0000000 |
+-----+-----------------+-----------------------+
加法和减法¶
对于加法或减法:
输出的前导位数是输入的最大前导位数加上 1(以保留进位值)。
输出的小数位数是输入的最大小数位数。
换言之,假设一个加法或减法运算有两个输入(L1.S1
和 L2.S2
),输出中的最大位数计算如下:
- 前导数字:
L = max(L1, L2) + 1
- 小数位数:
S = max(S1, S2)
- 精度:
P = L + S
其他 N 元运算¶
对于具有多个数字输入的所有其他算术运算,例如模(a % b
或 MOD):
输出的前导位数是输入的最大前导位数。
输出的小数位数是输入的最大小数位数。
换言之,假设对输入 L1.S1
、L2.S2
等进行 N 元运算,则输出中的最大位数计算如下:
- 前导数字:
L = max(L1, L2, ...)
- 小数位数:
S = max(S1, S2, ...)
- 精度:
P = L + S
一元运算¶
一元算术运算的输出精度和小数位数与输入精度和小数位数相同,但允许显式指定输出小数位数的 ROUND 除外。
按位运算¶
支持的按位算术运算列表可在 条件表达式函数 中找到。
注意:
对于数值,按位运算仅对输入中的前导数字进行运算。输出的小数位数始终为零。
对于二进制按位运算,输出的前导位数与输入中的最大前导位数相同。