Deterministik olmayan şamandıralar toplamı


10

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.2tam 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.#ALEFT JOININNER JOIN

Bir; çünkü bu, uygunsuz DISTINCT, GROUP BYya 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ı?

Yanıtlar:


15

Aslında, bahsettiğiniz bağlantı kayan nokta aritmetik hesaplamalarının her zaman belirleyici olduğunu söylemez. Aslında, cevaplardan birinde, eklemenin çağrışımsal olmadığı (yani (a + b) + cmutlaka eşit olması gerekmediği a + (b + c)) belirtilmiştir, ki bu cevapta da söylenir .

Her bir grubun satırlarını farklı sırayla işlemek için akış birleştirme gerçekleşirse - SQL Server genellikle ücretsizdir; ORDER BYuygun maddede hayır yoksa, optimizer, eklemeleri hangi sırayla gerçekleştirdiğine bakılmaksızın, tarama veya arama veya diğer sorgu operatörünün en hızlı olacağını seçecektir - bu, gözlemlediğiniz davranışı açıklayabilir.

Toplama her zaman deterministiktür: aynı iki şamandırayı yerleştirirsiniz, aynı şamandırayı çıkarırsınız. Ancak şamandıraları farklı bir sırada bir araya getirmek farklı bir sonuç verebilir.


İlişkiliğin determinizmle bir ilişkisi yoktur, bu yüzden biraz yanıltıcıdır.
Mooing Duck

Kayan nokta eklemenin ilişkilendirilememesi, SQL Server toplama işlevinin deterministik olmayan davranışına yol açar SUM(), @MooingDuck kabul eder misiniz?
1919'da mustaccio

Hayır? Tamsayı Bölümü açık bir karşı örnektir. İlişkisel değildir, ancak tamamen belirleyicidir. Benzer şekilde, kayan nokta bölümü ilişkisel olmamalı ve hala deterministik olmalıdır. Bundan sonra, eklemenin çağrışımcı olmayan ve hala deterministik olmasının makul olduğu sonucuna vardık. Bununla birlikte, eklemelerin sırası belirleyici değilse, sonuç aynı şekilde belirleyici olmayacaktır, bu nedenle ilk ve son cümleniz yine de doğrudur.
Mooing Duck

Tamsayı bölümü SUM()kayan nokta bağımsız değişkenleri üzerinden SQL Server için bir karşı örnek , tam olarak nasıl?
mustaccio

1
Tamsayı bölümü ilişkisel ve deterministik değildir. Bu nedenle, aritmetik işlemler ilişkilendirilebilirliği determinizmle ilişkili değildir. Bu nedenle, herhangi bir ilişkisizliği, SUM()kendi determinizmi ile alakasız olmalıdır. Bunun SUMdeterministik olmadığı anlaşılıyor, ancak ilişkisizlikten söz etmelisiniz, çünkü bu ilgisiz.
Mooing Duck
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.