명백한 주먹을 말하겠습니다 : 부동 소수점 유형은 정확하게 10 진수 값을 나타낼 수 없다는 것을 완전히 이해합니다 . 이것에 관한 것이 아닙니다! 그럼에도 불구하고 부동 소수점 계산은 결정 론적이어야 합니다.
이제이 방법이 중단되었으므로 오늘 관찰 한 호기심이 많은 사례를 보여 드리겠습니다. 부동 소수점 값의 목록이 있으며 그 값을 요약하고 싶습니다.
CREATE TABLE #someFloats (val float);
INSERT INTO #someFloats (val) VALUES (1), (1), (1.2), (1.2), (1.2), (3), (5);
SELECT STR(SUM(#someFloats.val), 30, 15) FROM #someFloats;
DROP TABLE #someFloats;
-- yields:
-- 13.600000000000001
여태까지는 놀랍지 않습니다. 우리 1.2
는 정확하게 이진 표현으로 표현 될 수 없다는 것을 알고 있으므로 "부정확 한"결과가 예상됩니다.
이제 다른 테이블에 남아있을 때 다음과 같은 이상한 일이 발생합니다.
CREATE TABLE #A (a int);
INSERT INTO #A (a) VALUES (1), (2);
CREATE TABLE #someFloats (val float);
INSERT INTO #someFloats (val) VALUES (1), (1), (1.2), (1.2), (1.2), (3), (5);
SELECT #A.a, STR(SUM(#someFloats.val), 30, 15)
FROM #someFloats LEFT JOIN #A ON 1 = 1
GROUP BY #A.a;
DROP TABLE #someFloats;
DROP TABLE #A;
-- yields
-- 1 13.600000000000001
-- 2 13.599999999999998
( sql fiddle , 거기에서 실행 계획을 볼 수도 있습니다)
동일한 값에 대해 동일한 합계가 있지만 부동 소수점 오류가 다릅니다 . table에 행을 더 추가하면 두 값 사이에서 값이 번갈아 나타납니다. 이 문제는 다음과 같이 재현 할 수 없었습니다 . 여기 예상대로 작동합니다.#A
LEFT JOIN
INNER JOIN
그것이 있다는 것을 의미하기 때문에, 불편 DISTINCT
, GROUP BY
또는 PIVOT
(우리는이 문제를 발견하는 방법을 실제로하는) 다른 값으로 그들을보고있다.
확실한 해결책은 가치를 반올림하는 것이지만 궁금합니다.이 행동에 대한 논리적 설명이 있습니까?