2016-05-09 3 views
-1

Wir sind eine Migration in unserem Tool. Einige der Datentypen in unseren Tabellen wurden von Real in Float geändert. Um zu verstehen, die Auswirkungen Ich habe den folgenden Code ausführen:SQL Server Real und Float Datentyp Cast Konvertierungen stimmen nicht überein

declare @realVariable as real, 
@floatVariable as float 

set @realVariable=152304.11999512 
set @floatVariable=152304.11999512 

select cast(@realVariable AS decimal(15, 4)) as realcol,str(@floatVariable,15,4) as floatcol 

Das Ergebnis unterscheidet sich für sowohl reale als auch Float-Variablen: Real = 152304,1250 float = 152304,1200

Wie kann ich sicherstellen, dass der Schwimmer Ergebnis ist das gleiche wie echt?

+0

'SELECT CAST (CAST (152304.11999512 ALS REAL) ALS FLOAT) ALS DEZIMAL (15,4))'? –

+0

Obwohl ich nicht sicher bin, warum Sie ein weniger genaues Ergebnis wollen. –

Antwort

0

Sie benötigen ein Delta. Berechnen Sie den absoluten Wert der Differenz zwischen den reellen Werten und den Gleitkommawerten und stellen Sie sicher, dass dieser Wert kleiner als Ihr Delta ist. Das Delta sollte ausreichend klein sein, um Ihre Anforderungen zu erfüllen.

Zum Beispiel mit Ihren Werten: abs (152304.1250 - 152304.1200) < = .0050 also die Verwendung .0050 als Delta-Wert.

+0

In unserem Fall macht 0,0050 einen großen Unterschied, daher können wir uns kein Delta leisten. –

+0

Dann haben Sie Ihre eigene Frage beantwortet. Für Ihre Zwecke können Sie ein Real mit einem Float nicht zuverlässig vergleichen. – nicomp

+1

@Somita, wenn Präzision für Sie wichtig ist, sollten Sie nicht real oder float, sondern einen exakten numerischen Datentyp verwenden. Beide Zahlen sind derzeit Näherungswerte. – HLGEM

1

float und real sind beide ungefähre Datentypen für Gleitkommazahlen.

real ist das gleiche wie float (24). Wenn Sie float ohne Suffix deklarieren, dann bedeutet das float (53).

Sie konvertieren also von real (das ist float (24)) zu float (53). Sie machen einfach die Zahlen präziser.

float (24) hat eine Genauigkeit von 7 Ziffern und float (53) hat eine Genauigkeit von 15 Ziffern.

See Bücher Online> float und real (Transact-SQL): https://msdn.microsoft.com/en-GB/library/ms173773.aspx

Wenn wir Ihr Beispiel wiederholen und die Variablen ohne Konvertierung anzuzeigen, können wir mit 7 Ziffern Genauigkeit sehen, dass die Real-Variable angezeigt und Schwimmer Variable wird mit 14 Ziffern Genauigkeit angezeigt, was ist genau das, was Sie einstellen.

DECLARE @realVariable as real, 
@floatVariable as float; 

-- Set to a number with 14 digits precision 
SET @realVariable=152304.11999512; 
SET @floatVariable=152304.11999512; 

SELECT @realVariable AS '@realVariable', @floatVariable AS '@floatVariable'; 

enter image description here

Die einfache Antwort auf Ihre Frage ist, dass die beiden Zahlen nicht gleich sind. Der mit Schwimmer (53) ist genauer.

Das Berechnen der ABS der Differenz der zwei Zahlen und dann das Vergleichen mit einer akzeptablen Schwelle ist eine Möglichkeit, dies zu tun. Dies wäre jedoch nicht zufriedenstellend, wenn der Maßstab stark variieren könnte.

Um zu zeigen, warum dies nicht zufriedenstellend sein könnte:

r = 0.00
f = 0.00

den Unterschied zu einer Schwelle von 0,0005 wäre nicht sinnvoll sein Vergleich.

Es könnte also besser sein, einen Schwellenwert zu verwenden, der ein Prozentsatz der Anzahl ist.

DECLARE @threshold AS float, @delta AS float; 
SET @threshold = ABS(@floatVariable/1000000); 
SET @delta = ABS(@floatVariable - CAST(@realVariable AS float)); 

SELECT @realVariable AS '@realVariable', 
    @floatVariable AS '@floatVariable', 
    @threshold AS '@threshold', 
    @delta AS '@delta', 
    CASE 
     WHEN @delta < @threshold THEN N'OK' 
     ELSE N'Different' 
    END AS 'Comparison'; 

enter image description here

Hinweis: Diese Lösung könnte ein wenig Anpassung für Zahlen müssen, die sehr nahe bei Null sind.

+0

"Dies wäre jedoch nicht zufriedenstellend, wenn die Skala stark variieren kann." - Sicher wäre es. Maßstab und Präzision sind nicht dasselbe. – nicomp

1

@ RichardCL Beschreibung beschreibt die Art und Weise Dinge funktionieren (+1). Wenn Sie nun einen Wert, der als real Datentypwert gespeichert ist, in einen Wert umwandeln, der als float Datentypwert gespeichert ist, dann wird der gesamte und genaue "Original" -Wert im resultierenden Wert gespeichert - Sie verlieren keine Informationen von Ihrem vorhandenen Satz von real Werte.

Mit Bezug auf Ihr Beispiel kann Ihr Wert von 152304.11999512 nicht genau als real Wert gespeichert werden - er wird gerundet und als 152304.125 gespeichert. Konvertieren Sie dies in eine float, und Sie werden immer noch 152304.125 haben.

+0

Der Eindruck, den ich von der Frage habe, ist, dass die Zahlen neu berechnet werden, aber das könnte nicht so sein. – RichardCL

+0

Ich interpretierte es als "wir haben unsere Spalten von Real zu Float geändert, sind die gespeicherten Zahlen immer noch ok"? Also ja, das eigentliche Problem ist ein wenig vage. –

Verwandte Themen