2010-04-02 8 views
17

부동 소수점 값에 대한 비교 결과가 항상 올바른 결과를 반환하지 않는 부동 소수점 열을 MySQL 데이터베이스 스키마에 도입하여 문제가 발생했습니다.MySQL 부동 소수점 비교 문제

1-50.12
2-34.57
3-12.75
4 - ...이 "3"저를 반환

SELECT COUNT(*) FROM `users` WHERE `points` > "12.75" 

(모든 적은 12.00보다 휴식).

나는 MySQL의 부동 소수점 값 비교가 좋지 않으며 10 진수 타입이 더 좋은 옵션이라는 것을 읽었습니다.

나는 float 유형으로 계속 나아가고 비교가 올바르게 작동하기를 바랍니다.

+0

SQL에서 큰 따옴표로 묶인 리터럴은 무엇입니까? – Joey

+1

MySQL에서는 큰 따옴표가 기본적으로 작은 따옴표처럼 작동하도록 허용합니다. 이 기능은'ANSI_QUOTES' 옵션으로 해제 할 수 있습니다.이 옵션은 ANSI SQL 표준 (위 쿼리의 비표준 백틱과 같은)에 따라 식별자를 참조하게합니다. – bobince

+1

12.75는 정확하게 이진수 (1100.11)로 나타낼 수 있으므로 테스트 "> 12.75"를 어떻게 통과하는지는 알 수 없습니다. 당신의 목록에 12.75 이상의 다른 점이 없다고 확신합니까? –

답변

23

아래의 문제가 보입니까?

CREATE TABLE a (num float); 

INSERT INTO a VALUES (50.12); 
INSERT INTO a VALUES (34.57); 
INSERT INTO a VALUES (12.75); 
INSERT INTO a VALUES (11.22); 
INSERT INTO a VALUES (10.46); 
INSERT INTO a VALUES (9.35); 
INSERT INTO a VALUES (8.55); 
INSERT INTO a VALUES (7.23); 
INSERT INTO a VALUES (6.53); 
INSERT INTO a VALUES (5.15); 
INSERT INTO a VALUES (4.01); 

SELECT SUM(num) FROM a; 
+-----------------+ 
| SUM(num)  | 
+-----------------+ 
| 159.94000005722 | 
+-----------------+ 

일부 행 사이에 여분의 0.00000005722이 있습니다. 따라서 이러한 값 중 일부는 초기화 된 값과 비교할 때 false를 반환합니다.

ALTER TABLE a MODIFY num DECIMAL(6,2); 

SELECT SUM(num) FROM a; 
+----------+ 
| SUM(num) | 
+----------+ 
| 159.94 | 
+----------+ 
1 row in set (0.00 sec) 
+0

안녕 다니엘! 감사. 내 열 유형을 DECIMAL로 변환 할 것을 고려 중입니다. –

+1

@Sharief :'DECIAML '로의 변환이 불가능하다면, 내가 볼 수있는 유일한 옵션은 다음과 같이 쿼리를 작성할 수 있도록 부동 소수점 비교를 허용하는 것입니다 :'SELECT COUNT (*) FROM users WHERE points> 12.75 + 0.001);'... 그러나 정확도가 가장 중요한 경우 고정 소수점 'DECIMAL'이 최선의 방법입니다. 'DECIMAL'에 대한 또 다른 대안은'50.12' 대신에'5012'를 백분율로 표현하기 위해 확장 된 정수 값을 사용할 수 있습니다. 이것이 적절한 상황이있을 수 있습니다. –

+0

나는 여러분이 언급 한 것과 같은 관용을 이미 추가하려고 시도 했었습니다. 심지어 그 결과가 결코 일관 적이 지 않았습니다. –

1

부동 소수점입니다. 그래서 무엇이 문제입니까? 3은 올바른 결과 일 수 있으며, 데이터베이스가 12.75에 대해 생각하는 것에 달려 있습니다. 12.75입니까 아니면 조금 더 있습니까?

정확한 숫자를 원하면 DECIMAL을 사용하십시오.

+0

안녕하세요 프랭크, 당신이 "데이터베이스가 12.75에 대해 생각하는 것"이 ​​무엇을 의미하는지 자세히 설명해주십시오. 2 자리 정밀도 값과 3 자리 정밀도를 비교하려고하면 문제가 될 것입니다. Like ... Select Points (*) FROM'users' WHERE'points'> "12.751" –

+0

@ShariefShaik 저는 Decimal이 다른 사용자 경험에서 그 문제를 해결해야한다고 생각합니다. – gumuruh

1

플로트와 평등의 비교에 문제가 있습니다. 이것은 예기치 않은 결과를 줄 수 있습니다. 이는 부동 소수점 연산의 내부 구현 때문입니다.

0

숫자와 문자열 비교하기?

2

내가 한 번 유사한 문제에 직면했다 :

하는 부동 소수점 연산과 비교 문제를 방지하려면 DECIMAL 데이터 유형을 사용해야합니다. 'float'필드를 'decimal'로 변환하십시오. 그것은 확실히 문제를 해결할 것입니다.

+0

float의 정확한 고정 길이를 사용하여이 문제를 이미 해결했다고 생각했기 때문에 문제가 해결되지 않았습니다. ?? 예를 들면; float (4,2)를 정의합니다. 그리고 12.50의 값을 저장했습니다. 그런 다음 "> 12.50"문과 비교하려고합니다. 아직도 실패하지 않을까요? – gumuruh

1

나는이

WHERE abs(value - 12.75)<0.001 

할 수 있지만 모든 언어는 평등을 떠 비교할 수 있으며, 저장된 값은 정확한 수치에 해당하면 삽입을 값 경우 만 부부와 함께 어떤 문제

가 안 동의 십진수와 정확한 일치 값의 경우 정밀도 오류가 MySQL의 이러한 불일치에 대한 명백한 이유처럼 들리지 않음