Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Moy de l'incohérence du flotteur

Ceci est très similaire à :SELECT SUM(...) is non-deterministic when adding the column-values of datatype float .

Le problème est qu'avec un type de données inexact (FLOAT/REAL ) l'ordre des opérations arithmétiques sur les questions à virgule flottante. Démo de connect :

DECLARE @fl FLOAT = 100000000000000000000
DECLARE @i SMALLINT = 0
WHILE (@i < 100)
BEGIN
    SET @fl = @fl + CONVERT(float, 5000)
    SET @i = @i + 1
END
SET @fl = @fl - 100000000000000000000
SELECT CONVERT(NVARCHAR(40), @fl, 2)
-- 0.000000000000000e+000


DECLARE @fl FLOAT = 0
DECLARE @i SMALLINT = 0
WHILE (@i < 100)
BEGIN
    SET @fl = @fl + CONVERT(float, 5000)
    SET @i = @i + 1
END
SET @fl = @fl + 100000000000000000000
SET @fl = @fl - 100000000000000000000
SELECT @fl
-- 507904

LiveDemo

Solutions possibles :

  • CAST tous les arguments à un type de données précis comme DECIMAL/NUMERIC
  • modifier la table et changer FLOAT à DECIMAL
  • vous pouvez essayer de forcer l'optimiseur de requête à calculer la somme avec le même ordre.

La bonne nouvelle est que lorsqu'un résultat de requête stable est important pour votre application, vous pouvez forcer l'ordre à être le même en empêchant le parallélisme avec OPTION (MAXDOP 1) .

Il semble que le lien initial soit mort. WebArchives