부동 데이터 유형과 10진 데이터 유형의 차이
MySQL에서 float 및 10진수 데이터 유형을 사용하는 경우 어떤 차이가 있습니까?
어떤 것을 언제 사용하면 좋을까요?
이게 내가 이런 의심을 했을 때 찾은 거야
mysql> create table numbers (a decimal(10,2), b float);
mysql> insert into numbers values (100, 100);
mysql> select @a := (a/3), @b := (b/3), @a * 3, @b * 3 from numbers \G
*************************** 1. row ***************************
@a := (a/3): 33.333333333
@b := (b/3): 33.333333333333
@a + @a + @a: 99.999999999000000000000000000000
@b + @b + @b: 100
소수점은 이 경우에서 해야 할 일을 정확히 했고 나머지는 잘라서 1/3 부분을 잃었습니다.
따라서 합계의 경우 소수점이 더 낫지만 분할의 경우 부동선이 더 낫습니다. 물론 어느 정도까지는요.DIMAL을 사용한다고 해서 "불합격 산술"이 나오는 것은 아닙니다.
이게 도움이 됐으면 좋겠다.
대부분의 환경에서 "플로트"는 이진 부동 소수점 유형입니다.base-2 값은 정확하게 저장할 수 있지만(특정 지점까지), 다수의 base-10(10진수) 값은 정확하게 저장할 수 없습니다.플로트는 과학적 계산에 가장 적합합니다.그것들은 대부분의 비즈니스 지향적인 수학에 적합하지 않고, 부적절한 플로트 사용은 여러분을 물게 할 것입니다.많은 10진수 값은 2진수로 정확하게 나타낼 수 없습니다. 0.1
할 수 없기 에 이상한 를 볼 수 .1.0 - 0.1 = 0.8999999
.
소수점에는 10자리 숫자가 저장됩니다.10진수는 대부분의 비즈니스 산술에 적합한 유형입니다(단, 재무 계산에는 내장된 "돈" 유형이 더 적합합니다). 값의 범위가 정수형이 제공하는 범위를 초과하여 소수 값이 필요합니다.소수점은 이름에서 알 수 있듯이 10진수를 기준으로 설계되어 있으며, 소수점 값을 정확하게 저장할 수 있습니다(특정 점까지).
MySQL은 최근 DIMAL 유형을 저장하는 방법을 변경했습니다.과거에는 숫자 대 2의 보완 정수 또는 그 일부 도함수의 ASCII(또는 니블) 표현으로 구성된 각 숫자의 문자(또는 니블)를 저장했습니다.
DIMAL의 현재 저장 형식은 1, 2, 3, 또는 4바이트 정수로 이루어진 일련의 형식으로, 비트는 사용자가 정의한 암묵적인 10진수를 사용하여 2의 보수를 생성하고 열을 선언하고 DIMAL 크기와 소수점 위치를 지정할 때 DB 스키마에 저장됩니다.
예를 들어 32비트 int를 사용하는 경우 0 ~4,294,967,295 의 임의의 숫자를 저장할 수 있습니다.이것은 999,999,999만을 커버하기 때문에 2비트를 버리고 (1<30-1)을 사용했을 경우, 아무것도 포기하지 않습니다.9 자리수의 모든 숫자를 4 바이트만으로 커버하는 것은, 4 개의 ASCII 문자 또는8 개의 니블 숫자를 사용해 32 비트로 4 자리수를 커버하는 것보다 효율적입니다.(nyble은 4비트로, 0~9에 필요한 값보다 많은 값 0~15를 사용할 수 있지만, 3비트로 이동하는 것으로는 낭비를 없앨 수 없습니다.그것은 0~7의 값만을 커버하기 때문입니다).
MySQL 온라인 문서에서 사용되는 예에서는 DIMAL(18,9)을 예로 사용합니다.이는 위에서 설명한 바와 같이 다음 스토리지가 필요한 암묵적 소수점보다 9자리 앞과 9자리 뒤입니다.
18개의 8비트 문자로: 144비트
18개의 4비트 Nybl: 72비트
2개의 32비트 정수로서: 64비트
현재 DIMAL은 최대 65자리의 숫자를 지원합니다.M 의 최대 허용치는 65, D 의 최대 허용치는 30 입니다.
한 번에 9자리 청크가 필요하지 않도록 32비트 미만의 정수를 사용하여 1, 2, 3바이트 정수를 사용하여 숫자를 추가합니다.어떤 이유로든 논리에 어긋나는 서명되지 않은 int 대신 서명된 int가 사용되었으며, 그 결과 1비트가 폐기되어 다음과 같은 스토리지 기능이 발생합니다.1, 2, 4바이트 int의 경우 손실 비트는 문제가 되지 않지만, 3바이트 int의 경우 단일 비트의 손실로 인해 숫자 전체가 손실되기 때문에 큰 문제가 됩니다.
7비트 int: 0 ~99
15비트 int: 0 ~9,99
23비트 int의 경우: 0 ~999 (24비트 int의 경우 0 ~999,999)
1, 2, 3, 4바이트 정수를 연결하여 DIMAL이 숫자를 2의 보완 정수로 정확하게 나타내기 위해 사용하는 "비트 풀"을 형성합니다.소수점은 저장되지 않고 암시됩니다.
즉, DB엔진은 ASCII에서 int로 변환할 필요가 없습니다.이 경우, 「숫자」를 CPU가 수치로 인식하는 것으로 변환합니다.반올림이나 변환 에러 없이 CPU로 조작할 수 있는 실수입니다.
이 임의의 큰 정수에 대한 계산은 소프트웨어에서 수행되어야 합니다. 왜냐하면 이 숫자에 대한 하드웨어 지원이 없기 때문입니다. 그러나 이러한 라이브러리는 IBM 370 Fortran 임의 정밀 부동 소수점 데이터를 지원하기 위해 50년 전에 작성되었기 때문에 매우 오래되고 매우 최적화되어 있습니다.CPU 정수 하드웨어나 FPU에서 실행되는 부동소수점 계산보다 훨씬 느립니다.
스토리지 효율성 측면에서는 부동의 지수가 각 부동에 연결되어 소수점 위치를 암묵적으로 지정하기 때문에 이중화되므로 DB 작업에 비효율적입니다.DB에서는 이미 소수점의 위치를 알고 있기 때문에 DIMAL 열의 값이 있는 테이블 내의 각 행은 M 및 D 값의 의미로서 DIMAL(M, D)에 대한 인수로 스키마에 저장되는1 & 유일한 지정만 참조하면 됩니다.
여기서 볼 수 있는 다양한 어플리케이션에서 어떤 포맷을 사용하는지에 대한 많은 코멘트가 맞기 때문에 요점을 강조하지는 않겠습니다.링크된 MySQL 온라인 문서를 관리하는 사람이 누구든 위의 내용을 전혀 이해하지 못하기 때문에 시간을 들여 여기에 이 문서를 작성하게 되었습니다.또, 몇번이나 설명을 하려고 해도, 점점 더 짜증나는 시도를 하고 나서, 저는 포기했습니다.그들이 쓰고 있는 것을 얼마나 제대로 이해하지 못했는지를 보여주는 좋은 증거는 주제에 대한 매우 혼란스럽고 거의 해독할 수 없는 프레젠테이션이다.
마지막으로 고정밀 부동소수점 연산이 필요한 경우 지난 20년간 부동소수점 코드에 엄청난 발전이 있었고 96비트와 쿼드러플 Precision 부동소수점 코드에 대한 하드웨어 지원이 코앞에 다가왔지만 저장된 값을 조작할 경우 우수한 임의 정밀 라이브러리가 존재합니다.중요한.
Float 타입과 10진 타입의 차이는 MySQL에만 국한된 것이 아니라 분수 값을 나타내는 방법입니다., 은 2진수로만 수 .{m*2^n | m, n Integers}
1/은 (오류 수 . 1/5와 같은 값은 (반올림 오류 없이) 정확하게 나타낼 수 없습니다. 역시 이지만 10진수 같은 숫자를 .{m*10^n | m, n Integers}
소수점은 여전히 1/3과 같은 숫자를 나타낼 수 없지만, 금융과 같은 많은 공통적인 분야에서는 종종 특정 소수점은 항상 충실도를 잃지 않고 표현될 수 있다고 예상한다., 10으로 하다 의 값을 나타낼 수 입니다.$0.20
(1달러 5분의 1), 그러한 상황에서는 선호됩니다.
십진법은 당신이 특정한 소수 자릿수를 원하는 돈과 같은 고정된 수량에 대한 것입니다.플로트는 보관용...부동 소수점 정밀도 수치.
mysql> CREATE TABLE num(id int ,fl float,dc dec(5,2));
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO num VALUES(1,13.75,13.75);
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO num VALUES(2,13.15,13.15);
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM num WHERE fl = 13.15;
Empty set (0.00 sec)
mysql> SELECT * FROM num WHERE dc = 13.15;
+------+-------+-------+
| id | fl | dc |
+------+-------+-------+
| 2 | 13.15 | 13.15 |
+------+-------+-------+
1 row in set (0.00 sec)
mysql> SELECT SUM(fl) ,SUM(dc) FROM num;
+--------------------+---------+
| SUM(fl) | SUM(dc) |
+--------------------+---------+
| 26.899999618530273 | 26.90 |
+--------------------+---------+
1 row in set (0.00 sec)
mysql> SELECT * FROM num WHERE ABS(fl - 13.15)<0.01;
+------+-------+-------+
| id | fl | dc |
+------+-------+-------+
| 2 | 13.15 | 13.15 |
+------+-------+-------+
1 row in set (0.00 sec)
도움이 될 것 같았습니다.
일반적으로 변동 값은 과학적 계산에 유용하지만 재무/화폐 가치에는 사용하지 마십시오.비즈니스 지향 산술의 경우 항상 10진수를 사용하십시오.
출처 : http://code.rohitink.com/2013/06/12/mysql-integer-float-decimal-data-types-differences/
정확도가 아닌 성능을 추구하는 경우 부동산을 사용한 계산이 소수점보다 훨씬 빠릅니다.
부동소수점 유형(대략값) - 부동소수점, 이중
FLOAT 및 DOUBLE 유형은 대략적인 숫자 데이터 값을 나타냅니다.MySQL은 단일 정밀도 값에는 4바이트, 이중 정밀도 값에는 8바이트를 사용합니다.
FLOAT의 경우 SQL 표준은 괄호 안의 FLOAT 키워드 뒤에 이어지는 비트 단위의 정밀도(지수의 범위는 제외)를 선택적으로 지정할 수 있습니다.MySQL은 이 옵션의 정밀도 사양도 지원하지만 정밀도 값은 스토리지 크기를 결정하는 데만 사용됩니다.0 ~ 23의 정밀도는 4바이트의 단정도 FLOAT 컬럼이 됩니다.24 ~ 53의 정밀도는 8바이트의 2배 정밀도 DUBLE 컬럼이 됩니다.
MySQL은 비표준 구문인 FLOAT(M,D) 또는 REAL(M,D) 또는 DUBLE PRECISION(M,D)을 허용합니다.여기서 "(M,D)"는 총 M자리까지 값을 저장할 수 있으며, 그 중 D자리는 소수점 이후일 수 있다.예를 들어, FLOAT(7,4)로 정의된 열은 표시될 때 -999.9999와 같습니다.MySQL은 값을 저장할 때 반올림을 수행하므로 999.00009를 FLOAT(7,4) 열에 삽입하면 대략 999.0001이 됩니다.
부동소수점 값은 근사치이며 정확한 값으로 저장되지 않기 때문에 비교에서 정확하게 처리하려고 하면 문제가 발생할 수 있습니다.또한 플랫폼 또는 구현에 종속되는 경우도 있습니다.
휴대성을 최대화하려면 대략적인 숫자 데이터 값을 저장해야 하는 코드는 정밀도나 자릿수를 지정하지 않고 FLOAT 또는 DUBLE PRECISION을 사용해야 합니다.
https://dev.mysql.com/doc/refman/5.5/en/floating-point-types.html
부동 소수점 값에 관한 문제
부동소수점 숫자는 근사치이며 정확한 값으로 저장되지 않기 때문에 혼란을 일으킬 수 있습니다.SQL 문에 기술된 부동소수점 값은 내부적으로 표현된 값과 다를 수 있습니다.부동 소수점 값을 정확하게 비교하려고 하면 문제가 발생할 수 있습니다.또한 플랫폼 또는 구현에 종속되는 경우도 있습니다.FLOAT 및 DUBLE 데이터 유형은 이러한 문제에 해당됩니다.DIMAL 열의 경우 MySQL은 65자리 소수 정밀도로 연산을 수행하므로 대부분의 일반적인 부정확성 문제를 해결할 수 있습니다.
다음 예제에서는 DUBLE을 사용하여 부동소수점 연산을 사용한 계산에서 부동소수점 오류가 발생하는 방법을 보여 줍니다.
mysql> CREATE TABLE t1 (i INT, d1 DOUBLE, d2 DOUBLE);
mysql> INSERT INTO t1 VALUES (1, 101.40, 21.40), (1, -80.00, 0.00),
-> (2, 0.00, 0.00), (2, -13.20, 0.00), (2, 59.60, 46.40),
-> (2, 30.40, 30.40), (3, 37.00, 7.40), (3, -29.60, 0.00),
-> (4, 60.00, 15.40), (4, -10.60, 0.00), (4, -34.00, 0.00),
-> (5, 33.00, 0.00), (5, -25.80, 0.00), (5, 0.00, 7.20),
-> (6, 0.00, 0.00), (6, -51.40, 0.00);
mysql> SELECT i, SUM(d1) AS a, SUM(d2) AS b
-> FROM t1 GROUP BY i HAVING a <> b;
+------+-------+------+
| i | a | b |
+------+-------+------+
| 1 | 21.4 | 21.4 |
| 2 | 76.8 | 76.8 |
| 3 | 7.4 | 7.4 |
| 4 | 15.4 | 15.4 |
| 5 | 7.2 | 7.2 |
| 6 | -51.4 | 0 |
+------+-------+------+
결과는 정확합니다.처음 5개의 레코드는 비교를 만족시키지 않는 것처럼 보이지만(a와 b의 값은 다르지 않은 것으로 보인다), 컴퓨터 아키텍처나 컴파일러 버전이나 최적화 수준 등의 요소에 따라 숫자의 차이가 10진수 전후로 나타나기 때문에 그렇게 할 수 있습니다.예를 들어 CPU에 따라 부동소수점 숫자가 다르게 평가될 수 있습니다.
열 d1과 d2가 DUBLE이 아닌 DIMAL로 정의되어 있는 경우 SELECT 쿼리 결과에는 위의 마지막 행인1개만 포함됩니다.
부동소수점 숫자를 비교하는 올바른 방법은 먼저 숫자 간의 차이에 대해 허용 가능한 허용 오차를 결정한 후 허용 오차를 비교하는 것입니다.예를 들어 부동소수점 숫자가 10,000분의 1(0.0001)의 정밀도 내에서 동일한 것으로 간주할 경우 공차 값보다 큰 차이를 찾기 위해 비교를 작성해야 합니다.
mysql> SELECT i, SUM(d1) AS a, SUM(d2) AS b FROM t1
-> GROUP BY i HAVING ABS(a - b) > 0.0001;
+------+-------+------+
| i | a | b |
+------+-------+------+
| 6 | -51.4 | 0 |
+------+-------+------+
1 row in set (0.00 sec)
반대로 숫자가 같은 행을 얻으려면 검정에서 공차 값 내의 차이를 찾아야 합니다.
mysql> SELECT i, SUM(d1) AS a, SUM(d2) AS b FROM t1
-> GROUP BY i HAVING ABS(a - b) <= 0.0001;
+------+------+------+
| i | a | b |
+------+------+------+
| 1 | 21.4 | 21.4 |
| 2 | 76.8 | 76.8 |
| 3 | 7.4 | 7.4 |
| 4 | 15.4 | 15.4 |
| 5 | 7.2 | 7.2 |
+------+------+------+
5 rows in set (0.03 sec)
부동소수점 값은 플랫폼 또는 구현에 의존합니다.다음 문을 실행한다고 가정합니다.
CREATE TABLE t1(c1 FLOAT(53,0), c2 FLOAT(53,0));
INSERT INTO t1 VALUES('1e+52','-1e+52');
SELECT * FROM t1;
일부 플랫폼에서는 SELECT 문이 inf 및 -inf를 반환합니다.다른 경우에는 0과 -0을 반환합니다.
이전 문제의 시사점은 마스터에서 mysqldump를 사용하여 테이블 내용을 덤프하고 덤프 파일을 슬레이브로 다시 로드하여 복제 슬레이브를 생성하려고 하면 부동 소수점 열이 포함된 테이블이 두 호스트 간에 다를 수 있다는 것입니다.
https://dev.mysql.com/doc/refman/5.5/en/problems-with-float.html
하드&퍼스트 룰
저장할 숫자를 더하거나 빼거나 곱하기만 하면 되는 경우 DIMAL이 가장 좋습니다.
데이터를 나눗셈하거나 다른 형태의 산술이나 대수를 해야 하는 경우 플로트를 사용하면 더 행복해질 것입니다.부동소수점 라이브러리 및 인텔 프로세서의 부동소수점 프로세서 자체에는 일반적인 함수(특히 초월함수)를 실행할 때 발생하는 예외의 수정, 수정, 검출 및 처리를 위한 많은 작업이 있습니다.
정확성에 대해서는 3,600개의 예산단위에 대해 3,600개의 예산단위에 대해 매월 그 유닛의 통합노드에 대한 기여율을 계산하는 예산시스템을 작성한 적이 있습니다.그리고 그 비율 매트릭스(3,000+x12x3,600)를 바탕으로 최고 조직노드에 의해 책정된 예산을 다음 3단계로 곱했습니다.모든 3,200개의 상세 유닛에 대해 모든(3,000 + 12) 값을 계산한다.수백만의 배정밀 부동 소수점 계산, 그 중 어느 것이든 상향식 통합으로 모든 예측이 취소되어 조직 내 최고 수준으로 돌아갑니다.
모든 계산 후 부동소수점 총 오차는 0이었습니다.1986년의 일입니다.오늘날 부동소수점 도서관은 옛날보다 훨씬 좋아졌어요인텔은 80비트 정밀도로 두 배의 중간 계산을 실시하여 반올림 오차를 거의 없앱니다."부동소수점 오류"라고 말하는 사람은 사실이 아닌 것이 거의 확실합니다.
float
(그리고double
)는 이진수를 나타냅니다.
decimal
십진수를 나타내다
declare @float as float(10)
declare @Decimal as decimal(10)
declare @Inetger as int
set @float =10.7
set @Decimal =10.7
set @Inetger=@Decimal
print @Inetger
10진수 11의 정수 인쇄로 값을 설정할 때 플로트 단위
언급URL : https://stackoverflow.com/questions/5150274/difference-between-float-and-decimal-data-type
'programing' 카테고리의 다른 글
Android에서 현재 요일을 얻는 가장 쉬운 방법은 무엇입니까? (0) | 2022.09.04 |
---|---|
MySQL에서 외부 키 제약 조건을 추가할 수 없음 (0) | 2022.09.04 |
'sorted(list)'와 'list.sort()'의 차이점은 무엇입니까? (0) | 2022.09.04 |
익명 클래스에 대한 다중 상속 (0) | 2022.09.04 |
Python에서 문자열 서브스트링을 가져오려면 어떻게 해야 하나요? (0) | 2022.09.04 |