
# 数字操作函数和算术操作符
#### 算术操作符
M-Compatibility模式下的算术操作符包含+、-、\*、/、%、-（取负操作）和DIV，具体请参见[表1](https://support.huaweicloud.com/distributed-m-comp-devg-v8-gaussdb/gaussdb-81-0144.html#ZH-CN_TOPIC_0000002558805327__zh-cn_topic_0000002558053597_zh-cn_topic_0000001790097185_table1030093821715)。
- + 描述：进行加法操作。
  示例：
  ```
  /* plus constant */
  m_db=# SELECT 2+3;
   ?column? 
  ----------
          5
  (1 row)
  m_db=# SELECT +3;
   ?column? 
  ----------
          3
  (1 row)
  ```
  
- - 描述：进行减法操作或表示负数。
  ![](https://support.huaweicloud.com/distributed-m-comp-devg-v8-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
  如果两个操作数都是整数并且其中任何一个是无符号的，则结果是无符号整数。对于减法，如果启用NO_UNSIGNED_SUBTRACTION SQL模式，则即使任何操作数是无符号数，结果也会是有符号数。
  示例：
  ```
  /* minus constant */
  m_db=# SELECT 3-2;
   ?column? 
  ----------
          1
  (1 row)
  m_db=# SELECT -3;
   ?column? 
  ----------
         -3
  (1 row)
  ```
  
- \* 描述：进行乘法操作。
  示例：
  ```
  /* multiply constant */
  m_db=# SELECT 2*3;
   ?column? 
  ----------
          6
  (1 row)
  m_db=# SELECT -2*3;
   ?column? 
  ----------
         -6
  (1 row)
  ```
  
- / 描述：进行除法操作。
  ![](https://support.huaweicloud.com/distributed-m-comp-devg-v8-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
  在使用/进行除法运算时，使用两个精确值操作数时结果的小数位数是第一个操作数的小数位数加上div_precision_increment系统变量的值（默认为4）。例如，表达式8.85/0.093的结果有六个小数位 (95.161290)。
  示例：
  ```
  /* division constant */
  m_db=# SELECT 4/2;
   ?column? 
  ----------
     2.0000
  (1 row)
  m_db=# SELECT 8.85/0.093;
   ?column?  
  -----------
   95.161290
  (1 row)
  ```
  
- %或MOD 描述：进行取余操作。
  示例：
  ```
  /* mod constant */
  m_db=# SELECT 7%4;
   ?column? 
  ----------
          3
  (1 row)
  m_db=# SELECT 7 MOD 4;
   ?column?
  ----------
          3
  (1 row)
  ```
  
- DIV 描述：进行整除操作。
  示例：
  ```
  /* DIV test */
  m_db=# SELECT 2.1 DIV 1;
   ?column?
  ----------
          2
  (1 row)
  m_db=# SELECT 1 DIV 2;
   ?column?
  ----------
          0
  (1 row)
  ```
  
 
#### 算术操作符规格约束
操作符支持不同大类之间的数据进行操作。数据进行操作前，先将数据提升到相应的大类后再计算出相应的结果。操作符中操作数提升规则以及结果类型规格如[表1]所示。
 表1操作符中操作数提升规则 
| 左右入参类型                                                                                                                                      | 归类类型                                                                                                           |
|:---|:---|
| TINYINT、SMALLINT、MEDIUMINT、INT/INTEGER、BIGINT、DATE                                                                                          | BIGINT                                                                                                         |
| TINYINT UNSIGNED、SMALLINT UNSIGNED、MEDIUMINT UNSIGNED、INT/INTEGER UNSIGNED、BIGINT UNSIGNED、BIT、YEAR                                         | BIGINT UNSIGNED                                                                                                |
| TIME、TIMESTAMP、DATETIME                                                                                                                     | 对应BIGINT（不带毫秒的情况） 对应NUMERIC（带毫秒的情况） |
| UNKNOWN、CHAR、VARCHAR、BINARY、VARBINARY、TINYTEXT、TEXT、MEDIUMTEXT、LONGTEXT、TINYBLOB、BLOB、MEDIUMBLOB、LONGBLOB、JSON、SET、ENUM、FLOAT、FLOAT4、FLOAT8 | FLOAT8                                                                                                         |
| NUMERIC                                                                                                                                     | NUMERIC                                                                                                        |
| 其他默认                                                                                                                                        | BIGINT                                                                                                         |
   
表2加法、乘法、取模结果类型 
| **归类类型组合（从上到下优先级从高到低）** | **最终结果类型**      |
|:---|:---|
| FLOAT8 + 任意             | FLOAT8          |
| NUMERIC + 任意            | NUMERIC         |
| BIGINT UNSIGNED + 任意    | BIGINT UNSIGNED |
| 其他                      | BIGINT          |
   
表3减法结果类型 
| **归类类型组合（从上到下优先级从高到低）** | **最终结果类型**                                                                                                                                                                      |
|:---|:---|
| FLOAT8 + 任意             | FLOAT8                                                                                                                                                                          |
| NUMERIC + 任意            | NUMERIC                                                                                                                                                                         |
| BIGINT UNSIGNED + 任意    | BIGINT UNSIGNED或BIGINT (如果GUC参数SQL_MODE开启了NO_UNSIGNED_SUBTRACTION时，结果类型是BIGINT，否则返回BIGINT UNSIGNED。) |
| 其他                      | BIGINT                                                                                                                                                                          |
   
表4除法结果类型 
| **归类类型组合（从上到下优先级从高到低）** | **最终结果类型** |
|:---|:---|
| FLOAT8 + 任意             | float8     |
| 其他                      | numeric    |
   
表5取负结果类型 
| **入参类型**                                                                                                                                                                 | **结果类型** |
|:---|:---|
| TINYINT、SMALLINT、MEDIUMINT、INT/INTEGER、BIGINT、TINYINT UNSIGNED、SMALLINT UNSIGNED、MEDIUMINT UNSIGNED、INT/INTEGER UNSIGNED、BIGINT UNSIGNED、BIT、YEAR                        | BIGINT   |
| UNKNOWN、CHAR、VARCHAR、BINARY、VARBINARY、TINYTEXT、TEXT、MEDIUMTEXT、LONGTEXT、JSON、SET、ENUM、TINYBLOB、BLOB、MEDIUMBLOB、LONGBLOB、DATE、DATETIME、TIMESTAMP、TIME、FLOAT、FLOAT4、FLOAT8 | FLOAT8   |
| NUMERIC                                                                                                                                                                  | NUMERIC  |
| 其他默认                                                                                                                                                                     | FLOAT8   |
   
表6整除结果类型 
| **入参类型**                                                                                                                                                                         | **结果类型**                                  |
|:---|:---|
| TINYINT、SMALLINT、MEDIUMINT、INT/INTEGER、BIGINT、TINYINT UNSIGNED、SMALLINT UNSIGNED、MEDIUMINT UNSIGNED、INT/INTEGER UNSIGNED、BIGINT UNSIGNED、BIT、YEAR                                | BIGINT（入参转BIGINT大类型作除法运算，结果取整返回BIGINT类型。） |
| UNKNOWN、CHAR、VARCHAR、BINARY、VARBINARY、TINYTEXT、TEXT、MEDIUMTEXT、LONGTEXT、JSON、SET、ENUM、TINYBLOB、BLOB、MEDIUMBLOB、LONGBLOB、DATE、DATETIME、TIMESTAMP、TIME、FLOAT、FLOAT4、FLOAT8、NUMERIC | BIGINT（入参转DOUBLE大类型作除法运算，结果取整返回BIGINT类型。） |
   
![](https://support.huaweicloud.com/distributed-m-comp-devg-v8-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
在当算数操作符的操作数为返回值是datetime、timestamp和time类型的函数，或者返回值是datetime和time类型的字面量，如timestamp'2000-01-01 00:00:00'、time'08:00:00'的时候，会忽略小数点后的内容，即忽略掉毫秒信息。
#### 数字操作函数
- ABS(expr) 描述：求数值表达式的绝对值。
  参数：expr，数值表达式。
  返回值类型：BIGINT UNSIGNED、BIGINT、DOUBLE、DECIMAL。与数值表达式的数据类型相同。
  示例：
  ```
  m_db=# SELECT ABS(-1.3);
   abs 
  -----
   1.3
  (1 row)
  ```
  

- ACOS(X) 描述：返回X的反余弦值，即余弦为X的值。
  参数：X，取值范围不在\[-1、1\]区间内，该函数返回空值。
  返回值类型：DOUBLE
  示例：
  ```
  m_db=# SELECT ACOS(0);
          acos        
  --------------------
   1.5707963267948966
  (1 row)
  ```
  

- ASIN(X) 描述：返回X的反正弦值，即正弦为X的值。
  参数：X，取值范围不在\[-1、1\]区间内，该函数返回空值。
  返回值类型：DOUBLE
  示例：
  ```
  m_db=# SELECT ASIN(0);
   asin 
  ------
      0
  (1 row)
  ```
  

- ATAN(X) 描述：返回X的反正切值，即正切值为X的值。
  返回值类型：DOUBLE
  示例：
  ```
  m_db=# SELECT ATAN(-10);
          atan         
  ---------------------
   -1.4711276743037347
  (1 row)
  ```
  
- ATAN(Y, X)
  描述：返回X与Y的反正切值。它类似于计算Y/X的反正切值，两个参数的符号用于确定结果所在的象限。
  返回值类型：DOUBLE
  示例：
  ```
  m_db=# SELECT ATAN(-2, 2);
          atan         
  ---------------------
   -0.7853981633974483
  (1 row)
  ```
  
- ATAN2(Y, X) 描述：该函数的功能用法与[ATAN(Y, X)]相同。
  示例：
  ```
  m_db=# SELECT ATAN2(-2, 2);
          atan2        
  ---------------------
   -0.7853981633974483
  (1 row)
  ```
  

- CEILING(X) 描述：返回大于等于X的最小整数。
  返回值类型：BIGINT、DOUBLE、DECIMAL
  示例：
  ```
  m_db=# SELECT CEILING(-5.5);
   ceiling 
  ---------
        -5
  (1 row)
  ```
  

- COS(X) 描述：返回指定弧度X的余弦值。
  返回值类型：DOUBLE
  示例：
  ```
  m_db=# SELECT COS(0);
   cos 
  -----
     1
  (1 row)
  ```
  

- DEGREES(X) 描述：将参数X从弧度转换为度数并返回。
  返回值类型：DOUBLE
  示例：
  ```
  m_db=# SELECT DEGREES(PI());
   degrees 
  ---------
       180
  (1 row)
  ```
  

- EXP(X) 描述：返回自然底数e（2.7182818...）的X次幂。
  返回值类型：DOUBLE
  ```
  m_db=# SELECT EXP(2);
         exp        
  ------------------
   7.38905609893065
  (1 row)
  ```
  

- FLOOR(X) 描述：返回小于等于X的最大整数。
  返回值类型：BIGINT UNSIGNED、BIGINT、DOUBLE、DECIMAL
  示例：
  ```
  m_db=# SELECT FLOOR(5.5);
   floor 
  -------
       5
  (1 row)
  ```
  

- LN(X) 描述：返回X的自然对数，即X的以e（2.7182818...）为底的对数。
  返回值类型：DOUBLE
  示例：
  ```
  m_db=# SELECT LN(2);
           ln         
  --------------------
   0.6931471805599453
  (1 row)
  ```
  

- LOG(\[B, \]X) 描述：返回以B为底X的对数。缺省B参数时，以e（2.7182818...）为底。
  返回值类型：DOUBLE
  示例：
  ```
  m_db=# SELECT LOG(2);
          log         
  --------------------
   0.6931471805599453
  (1 row)
  m_db=# SELECT LOG(10, 2);
           log         
  ---------------------
   0.30102999566398114
  (1 row)
  ```
  

- LOG10(X) 描述：返回以10为底X的对数。
  返回值类型：DOUBLE
  ```
  m_db=# SELECT LOG10(2);
         log10        
  --------------------
   0.3010299956639812
  (1 row)
  ```
  

- LOG2(X) 描述：返回以2为底X的对数。
  返回值类型：DOUBLE
  ```
  m_db=# SELECT LOG2(2);
   log2 
  ------
      1
  (1 row)
  ```
  

- PI() 描述：返回π的值（圆周率）。
  返回值类型：DOUBLE
  示例：
  ```
  m_db=# SELECT PI();
          pi         
  -------------------
   3.141592653589793
  (1 row)
  ```
  

- POW(X, Y)
  描述：返回X的Y次方。
  返回值类型：DOUBLE
  示例：
  ```
  m_db=# SELECT POW(2, 3);
   pow 
  -----
     8
  (1 row)
  ```
  

- POWER(X, Y) 描述：返回X的Y次方。该函数是[POW(X, Y)]函数的别名。
  返回值类型：DOUBLE
  示例：
  ```
  m_db=# SELECT POWER(2, 3);
   power 
  -------
       8
  (1 row)
  ```
  

- RAND(\[seed\]) 描述：返回随机浮点数，范围\[0, 1)。
  参数：seed，随机数种子。指定相同的seed值该函数会生成相同的随机数。
  返回值类型：DOUBLE
  示例：
  ```
  m_db=# SELECT RAND();
          rand        
  --------------------
   0.5320404642261565
  (1 row)
  m_db=# SELECT RAND(1);
          rand         
  ---------------------
   0.40540353712197724
  (1 row)
  ```
  

- SIGN(X) 描述：返回X的符号对应的值，即正值返回1，零值返回0，负值返回-1。
  返回值类型：BIGINT
  示例：
  ```
  m_db=# SELECT SIGN(5.2);
   sign 
  ------
      1
  (1 row)
  m_db=# SELECT SIGN(0);
   sign 
  ------
      0
  (1 row)
  m_db=# SELECT SIGN(-5.2);
   sign 
  ------
     -1
  (1 row)
  ```
  

- SIN(X) 描述：返回指定弧度X的正弦值。
  返回值类型：DOUBLE
  示例：
  ```
  m_db=# SELECT SIN(PI());
            sin           
  ------------------------
   1.2246467991473532e-16
  (1 row)
  ```
  

- SQRT(X) 描述：返回X的平方根。
  返回值类型：DOUBLE
  示例：
  ```
  m_db=# SELECT SQRT(0.64);
   sqrt 
  ------
    0.8
  (1 row)
  ```
  

- TAN(X) 描述：返回指定弧度X的正切值。
  返回值类型：DOUBLE
  示例：
  ```
  m_db=# SELECT TAN(PI());
             tan           
  -------------------------
   -1.2246467991473532e-16
  (1 row)
  ```
  

- TRUNCATE(X, D) 描述：返回X保留D位小数的结果。
  参数：如果参数D为0，则返回X的整数部分。如果参数D为负数，则使X的小数点左侧D位数变为0。
  返回值类型：BIGINT、DOUBLE、DECIMAL
  示例：
  ```
  m_db=# SELECT TRUNCATE(3.2312, 1);
   truncate 
  ----------
        3.2
  (1 row)
  m_db=# SELECT TRUNCATE(123.2312, -1);
   truncate 
  ----------
        120
  (1 row)
  ```
  
 
#### 扩展场景
- 算术操作符优先级：取负 \> 乘=除=取余=整除 \> 加=减。 示例：乘法操作优先级高于加法操作
  ```
  m_db=# SELECT 1 + 2 * 3;
   ?column?
  ----------
          7
  (1 row)
  ```
  示例：取余操作优先级高于加法操作
  ```
  m_db=# SELECT 1 + 2 % 3;
   ?column?
  ----------
          3
  (1 row)
  ```
  示例：取模操作优先级高于加法操作
  ```
  m_db=# SELECT 1 + 2 MOD 3;
   ?column?
  ----------
          3
  (1 row)
  ```
  示例：整除操作优先级高于加法操作
  ```
  m_db=# SELECT 1 + 7 DIV 3;
   ?column?
  ----------
          3
  (1 row)
  ```
  
 
