Loading...
MySQL 9.5 Reference Manual 9.5의 14.25.5 Precision Math Examples의 한국어 번역본입니다.
아래의 경우에 피드백에서 신고해주신다면 반영하겠습니다.
감사합니다 :)
이 섹션은 MySQL에서 정밀 수학 쿼리 결과를 보여 주는 몇 가지 예를 제공합니다. 이러한 예제는 Section 14.25.3, “Expression Handling” 및 Section 14.25.4, “Rounding Behavior”에 설명된 원리를 보여 줍니다.
Example 1. 가능할 때는 숫자가 주어진 그대로의 정확한 값으로 사용됩니다:
1mysql> SELECT (.1 + .2) = .3; 2+----------------+ 3| (.1 + .2) = .3 | 4+----------------+ 5| 1 | 6+----------------+
부동 소수점 값의 경우, 결과는 부정확합니다:
1mysql> SELECT (.1E0 + .2E0) = .3E0; 2+----------------------+ 3| (.1E0 + .2E0) = .3E0 | 4+----------------------+ 5| 0 | 6+----------------------+
정확값 처리와 근삿값 처리의 차이를 확인하는 또 다른 방법은 작은 숫자를 합계에 여러 번 더해 보는 것입니다. 다음 저장 프로시저는 변수에
.0001을 1,000번 더합니다.
1CREATE PROCEDURE p () 2BEGIN 3 DECLARE i INT DEFAULT 0; 4 DECLARE d DECIMAL(10,4) DEFAULT 0; 5 DECLARE f FLOAT DEFAULT 0; 6 WHILE i < 10000 DO 7 SET d = d + .0001; 8 SET f = f + .0001E0; 9 SET i = i + 1; 10 END WHILE; 11 SELECT d, f; 12END;
d와 f에 대한 합은 논리적으로 1이 되어야 하지만, 이는 decimal 계산에만 해당합니다. 부동 소수점 계산은 작은 오류를 도입합니다:
1+--------+------------------+ 2| d | f | 3+--------+------------------+ 4| 1.0000 | 0.99999999999991 | 5+--------+------------------+
Example 2. 곱셈은 표준 SQL에서 요구하는 스케일로 수행됩니다. 즉, 스케일이
S1 및 _S2_인 두 숫자 X1 및
_X2_에 대해 결과의 스케일은 S1 + S2입니다:
1mysql> SELECT .01 * .01; 2+-----------+ 3| .01 * .01 | 4+-----------+ 5| 0.0001 | 6+-----------+
Example 3. 정확값 숫자에 대한 반올림 동작은 명확하게 정의되어 있습니다:
반올림 동작(예를 들어
ROUND() 함수 사용 시)은 기본 C 라이브러리 구현과 독립적이므로, 결과는 플랫폼 간에 일관됩니다.
DECIMAL 및 정수)과 정확값 숫자에 대한 반올림은 “round half away from
zero” 규칙을 사용합니다. 소수 부분이 .5 이상인 값은 다음 예와 같이 0에서 멀어지는 방향으로 가장 가까운 정수로 반올림됩니다:1mysql> SELECT ROUND(2.5), ROUND(-2.5); 2+------------+-------------+ 3| ROUND(2.5) | ROUND(-2.5) | 4+------------+-------------+ 5| 3 | -3 | 6+------------+-------------+
1mysql> SELECT ROUND(2.5E0), ROUND(-2.5E0); 2+--------------+---------------+ 3| ROUND(2.5E0) | ROUND(-2.5E0) | 4+--------------+---------------+ 5| 2 | -2 | 6+--------------+---------------+
Example 4. strict 모드에서는, 컬럼 범위를 벗어난 값을 삽입하면 적법한 값으로 잘리지 않고 에러가 발생합니다.
MySQL이 strict 모드로 실행되지 않는 경우, 적법한 값으로의 잘림이 발생합니다:
1mysql> SET sql_mode=''; 2Query OK, 0 rows affected (0.00 sec) 3 4mysql> CREATE TABLE t (i TINYINT); 5Query OK, 0 rows affected (0.01 sec) 6 7mysql> INSERT INTO t SET i = 128; 8Query OK, 1 row affected, 1 warning (0.00 sec) 9 10mysql> SELECT i FROM t; 11+------+ 12| i | 13+------+ 14| 127 | 15+------+ 161 row in set (0.00 sec)
그러나 strict 모드가 적용되어 있으면 에러가 발생합니다:
1mysql> SET sql_mode='STRICT_ALL_TABLES'; 2Query OK, 0 rows affected (0.00 sec) 3 4mysql> CREATE TABLE t (i TINYINT); 5Query OK, 0 rows affected (0.00 sec) 6 7mysql> INSERT INTO t SET i = 128; 8ERROR 1264 (22003): Out of range value adjusted for column 'i' at row 1 9 10mysql> SELECT i FROM t; 11Empty set (0.00 sec)
Example 5: strict 모드이고
ERROR_FOR_DIVISION_BY_ZERO가 설정된 경우, 0으로 나누기는 NULL 결과가 아니라 에러를 발생시킵니다.
nonstrict 모드에서는, 0으로 나누기의 결과가
NULL입니다:
1mysql> SET sql_mode=''; 2Query OK, 0 rows affected (0.01 sec) 3 4mysql> CREATE TABLE t (i TINYINT); 5Query OK, 0 rows affected (0.00 sec) 6 7mysql> INSERT INTO t SET i = 1 / 0; 8Query OK, 1 row affected (0.00 sec) 9 10mysql> SELECT i FROM t; 11+------+ 12| i | 13+------+ 14| NULL | 15+------+ 161 row in set (0.03 sec)
그러나 적절한 SQL 모드가 적용된 경우 0으로 나누기는 에러입니다:
1mysql> SET sql_mode='STRICT_ALL_TABLES,ERROR_FOR_DIVISION_BY_ZERO'; 2Query OK, 0 rows affected (0.00 sec) 3 4mysql> CREATE TABLE t (i TINYINT); 5Query OK, 0 rows affected (0.00 sec) 6 7mysql> INSERT INTO t SET i = 1 / 0; 8ERROR 1365 (22012): Division by 0 9 10mysql> SELECT i FROM t; 11Empty set (0.01 sec)
Example 6. 정확값 리터럴은 정확값으로 평가됩니다.
근삿값 리터럴은 부동 소수점을 사용해 평가되지만, 정확값 리터럴은
DECIMAL로 처리됩니다:
1mysql> CREATE TABLE t SELECT 2.5 AS a, 25E-1 AS b; 2Query OK, 1 row affected (0.01 sec) 3Records: 1 Duplicates: 0 Warnings: 0 4 5mysql> DESCRIBE t; 6+-------+-----------------------+------+-----+---------+-------+ 7| Field | Type | Null | Key | Default | Extra | 8+-------+-----------------------+------+-----+---------+-------+ 9| a | decimal(2,1) unsigned | NO | | 0.0 | | 10| b | double | NO | | 0 | | 11+-------+-----------------------+------+-----+---------+-------+ 122 rows in set (0.01 sec)
Example 7. 집계 함수의 인수가 정확값 수치형 타입이면, 결과 역시 인수와 최소한 같은 스케일을 가진 정확값 수치형 타입입니다.
다음 구문을 살펴보십시오:
1mysql> CREATE TABLE t (i INT, d DECIMAL, f FLOAT); 2mysql> INSERT INTO t VALUES(1,1,1); 3mysql> CREATE TABLE y SELECT AVG(i), AVG(d), AVG(f) FROM t;
부동 소수점 인수에 대해서만 결과가 double입니다. 정확값 타입 인수의 경우, 결과 역시 정확값 타입입니다:
1mysql> DESCRIBE y; 2+--------+---------------+------+-----+---------+-------+ 3| Field | Type | Null | Key | Default | Extra | 4+--------+---------------+------+-----+---------+-------+ 5| AVG(i) | decimal(14,4) | YES | | NULL | | 6| AVG(d) | decimal(14,4) | YES | | NULL | | 7| AVG(f) | double | YES | | NULL | | 8+--------+---------------+------+-----+---------+-------+
부동 소수점 인수에 대해서만 결과가 double입니다. 정확값 타입 인수의 경우, 결과 역시 정확값 타입입니다.
14.25.4 Rounding Behavior
15 SQL Statements