T-SQL Dezimalteilung Genauigkeit
Frage
Wer weiß, warum, mit SQL Server 2005
SELECT CONVERT(DECIMAL(30,15),146804871.212533)/CONVERT(DECIMAL (38,9),12499999.9999)
gibt mir 11,74438969709659,
aber wenn ich die Dezimalstellen auf dem Nenner zu 15 erhöhen, erhalte ich eine weniger genaue Antwort:
SELECT CONVERT(DECIMAL(30,15),146804871.212533)/CONVERT(DECIMAL (38,15),12499999.9999)
gib mir 11.74438969
Lösung
Für Multiplikation wir einfach die Anzahl der Nachkommastellen addieren zusammen in jedem Argumente (mit Stift und Papier) Ausgabe Dezember Orte zu arbeiten.
Aber Division gerade bläst den Kopf auseinander. Ich bin jetzt hinlegen aus.
In SQL Bedingungen ist es allerdings genau wie erwartet.
--Precision = p1 - s1 + s2 + max(6, s1 + p2 + 1)
--Scale = max(6, s1 + p2 + 1)
--Scale = 15 + 38 + 1 = 54
--Precision = 30 - 15 + 9 + 54 = 72
--Max P = 38, P & S are linked, so (72,54) -> (38,20)
--So, we have 38,20 output (but we don use 20 d.p. for this sum) = 11.74438969709659
SELECT CONVERT(DECIMAL(30,15),146804871.212533)/CONVERT(DECIMAL (38,9),12499999.9999)
--Scale = 15 + 38 + 1 = 54
--Precision = 30 - 15 + 15 + 54 = 84
--Max P = 38, P & S are linked, so (84,54) -> (38,8)
--So, we have 38,8 output = 11.74438969
SELECT CONVERT(DECIMAL(30,15),146804871.212533)/CONVERT(DECIMAL (38,15),12499999.9999)
Sie können die gleiche Mathematik tun, wenn folgen diese Regel auch wenn Sie behandeln jedes Zahlenpaar als
- 146.804.871,212533000000000 und 12.499.999,999900000
- 146.804.871,212533000000000 und 12499999,999900000000000
Andere Tipps
Um es kurz gesagt, verwenden DECIMAL (25,13), und Sie werden mit allen Berechnungen in Ordnung sein - Sie Präzision Recht bekommen als deklariert: 12 Stellen vor dem Dezimalpunkt und 13 Dezimalstellen nach. Regel: p + s muss 38 gleich und Sie werden auf sicheren Seite sein! Warum ist das? Aufgrund der sehr schlechten Implementierung der Arithmetik in SQL Server! Bis sie es zu beheben, folgen dieser Regel.
Ich habe bemerkt, dass, wenn Sie den Teilwert zu schweben werfen, gibt es Ihnen die richtige Antwort, das heißt:.
select 49/30 (result = 1)
würde:
select 49/cast(30 as float) (result = 1.63333333333333)
Wir waren über den magischen Übergang rätselhaft,
P & S sind miteinander verbunden, so:
(72,54) -> (38,29)
(84,54) -> (38,8)
Unter der Annahme, (38,29)
ein Tippfehler und soll (38,20)
werden, die folgende ist die Mathematik:
-
i. 72-38 = 34, ii. 54-34 = 20
-
i. 84-58 = 46, ii. 54-46 = 8
Und das ist die Begründung:
i. Ausgangsgenauigkeit kleiner max Präzision ist die Ziffern wir gehen weg zu werfen.
ii. Dann Ausgangsskale weniger das, was wir gehen wegzuwerfen gibt uns ... verbleibenden Stellen in der Ausgangsskala.
Hope, das hilft jemand anderen Sinn daraus zu machen versuchen.
Konvertieren des Ausdrucks nicht die Argumente.
select CONVERT(DECIMAL(38,36),146804871.212533 / 12499999.9999)
die folgende Verwendung kann helfen:
SELECT COL1 * 1.0 / COL2