Açık yumruğu belirteyim: Kayan nokta türlerinin ondalık değerleri doğru bir şekilde temsil edemediğini tamamen anlıyorum . Bu onunla ilgili değil! Bununla birlikte, kayan nokta hesaplamalarının deterministik olduğu varsayılmaktadır .
Şimdi bu yoldan çıktığı için size bugün gözlemlediğim meraklı vakayı göstereyim. Kayan nokta değerlerinin bir listesi var ve onları özetlemek istiyorum:
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
Şimdiye kadar, çok iyi - burada sürpriz yok. Hepimiz bunun 1.2
tam olarak ikili gösterimde temsil edilemeyeceğini biliyoruz , bu nedenle "kesin olmayan" sonuç bekleniyor.
Şimdi başka bir masaya katıldığımda şu garip şey oluyor:
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 keman , orada yürütme planını da görebilirsiniz)
Aynı değerler üzerinde aynı toplam var , ancak farklı bir kayan nokta hatası. Tabloya daha fazla satır eklersem , değerin bu iki değer arasında değiştiğini görebiliriz. Bu sorunu yalnızca bir ; burada beklendiği gibi çalışıyor.#A
LEFT JOIN
INNER JOIN
Bir; çünkü bu, uygunsuz DISTINCT
, GROUP BY
ya PIVOT
(biz bu sorunu nasıl keşfettiğini aslında olan) farklı değerler olarak görüyor.
Açık çözüm değeri yuvarlamaktır, ama merak ediyorum: Bu davranış için mantıklı bir açıklama var mı?