Delphi-PRAXiS
Seite 1 von 4  1 23     Letzte » 

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   MS SQL Genauigkeit in der Termauswertung (https://www.delphipraxis.net/200971-ms-sql-genauigkeit-der-termauswertung.html)

TigerLilly 12. Jun 2019 13:57

Datenbank: MS SQL • Version: 2008R2 • Zugriff über: MSSMS

MS SQL Genauigkeit in der Termauswertung
 
Das erwischt mich jetzt am falschen Fuß:

Dass das da

Code:
select 12/100*0.5
select 0.5/100*12
nicht dasselbe Ergebnis hat, verstehe ich ja noch.

Aber dass das auch nicht dasselbe Ergebnis hat

Code:
select 0.1*(12/100*0.5)
select 0.1*(0.5/100*12)
hätte ich nicht erwartet.

peterbelow 12. Jun 2019 14:07

AW: MS SQL Genauigkeit in der Termauswertung
 
Zitat:

Zitat von TigerLilly (Beitrag 1434446)
Das erwischt mich jetzt am falschen Fuß:

Dass das da

Code:
select 12/100*0.5
select 0.5/100*12
nicht dasselbe Ergebnis hat, verstehe ich ja noch.

Aber dass das auch nicht dasselbe Ergebnis hat

Code:
select 0.1*(12/100*0.5)
select 0.1*(0.5/100*12)
hätte ich nicht erwartet.

Wieso nicht? Wenn der Ausdruck in der Klammer schon nicht gleich ist (siehe oben), wieso soll es dann gleich werden wenn Du beides mit der gleichen Konstanten multiplizierst?

Computer rechnen binär und mit einer limitierten Zahl von Bits pro Variablen. Sowohl die Konvertierung Dezimal nach Binär als auch die Operatione selbst haben deshalb kleine Abweichungen vom mathematisch exakten Ergebnis, weshalb auch das Kommunitativgesetz nicht strikt erfüllt ist: das Ergebnis ist abhängig von der Reihenfolge, in der mathematische Operationen ausgeführt werden.

hoika 12. Jun 2019 14:09

AW: MS SQL Genauigkeit in der Termauswertung
 
Hallo,
Firebird macht es richtig ...
Es kommt in beiden Fällen 0.006 raus.

Vielleicht musst du noch ein Cast auf Double Precision machen:
select cast((0.1*(12/100*0.5) as double precision)

Moombas 12. Jun 2019 14:11

AW: MS SQL Genauigkeit in der Termauswertung
 
Also generell gilt normalerweise das die Positionen bei Punktrechnung beliebig tauschen kannst.

MS SQL scheint den "Bruch" (12/100 bzw. 0,5/100) nicht zu erkennen und zieht einfach die Punktrechnung vor. Daher bekommst du falsche und verschiedene Ergebnisse:

select 12/100*0.5 => 12/50 = 0.24
select 0.5/100*12 => 0.5/1200 = 0.00041666

Normalerweise wäre 0.06 das richtige Ergebnis.

bzw.

select 0.1*(12/100*0.5) => 0.1*(12/50) = 0.1*0.24 = 0.024
select 0.1*(0.5/100*12) => 0.1*(0.5/1200) = 0.1*0.00041666 = 0.000041666

Normalerweise wäre 0.006 das richtige Ergebnis.


Du müsstest also schreiben (ungetestet):

select (12/100)*0.5 => 0.12*0.5 = 0.06
select (0.5/100)*12 => 0.005*12 = 0.06

bzw.

select 0.1*(12/100)*0.5 = 0.006
select 0.1*(0.5/100)*12 = 0.006

TigerLilly 12. Jun 2019 14:16

AW: MS SQL Genauigkeit in der Termauswertung
 
Missverständnis. Erstes und zweites beispiel liefern natürlich unterschiedliche Ergebnisse. Sind ja auch mathematisch was anderes.

Das: select 12/100*0.5 liefert 0, während select 0.5*12/100 das erwartete Ergebnis liefert.

Meine Vermutung war, 12 als Integer die Genauigkeit vorgibt, sprich: keine Kommastellen.
Darum mein Versuch mit select 0.1*12/100*0.5 Kommastellen zu erzwingen, aber nada.

Die Doku sagt, dass Terme - also das 12/100 mit der Genauigkeit ihrer Operanden ausgewertet werden. Also ergibt 12/100 0.

Und nein: Der SQL Server kann schon richtig rechnen: Punkt vor Strich etc.

TigerLilly 12. Jun 2019 14:21

AW: MS SQL Genauigkeit in der Termauswertung
 
Zitat:

Zitat von hoika (Beitrag 1434451)
Hallo,
Firebird macht es richtig ...
Es kommt in beiden Fällen 0.006 raus.

Vielleicht musst du noch ein Cast auf Double Precision machen:
select cast((0.1*(12/100*0.5) as double precision)

Das hätte mein versuch mit dem 0.1* erzwingen sollen. Aber auch das CASTen hätte nichts genutzt, da 12/100 eben 0 ergibt.

Ich bin mir jetzt auch keiner Server-Einstellung bewusst, die das beeinflussen könnte.

Moombas 12. Jun 2019 14:24

AW: MS SQL Genauigkeit in der Termauswertung
 
Zitat:

Zitat von TigerLilly (Beitrag 1434453)
Die Doku sagt, dass Terme - also das 12/100 mit der Genauigkeit ihrer Operanden ausgewertet werden. Also ergibt 12/100 0.

Müsste dann nicht auch 0.5/100 auch 0 ergeben!? Und da in einer (reinen) Multiplikation einmal eine "0" vor kommt (bei beiden Rechenbeispielen!) wäre das Ergebnis BEIDER Beispiele 0, also sogar gleich. Aber du sagst das Ergebnis sei unterschiedlich, also kann diese Begründung nicht passen.

Delphi.Narium 12. Jun 2019 14:33

AW: MS SQL Genauigkeit in der Termauswertung
 
Was kommt denn bei Dir da so raus?

Firebird:
SQL-Code:
select 0.1 * (12 / 100 * 0.5) as a, 0.1 * (0.5 / 100 * 12) as b from dual;
liefert hier 0 und 0

SQL-Code:
select 0.1 * (12 / 100 * 0.500) as a, 0.1 * (0.500 / 100 * 12) as b from dual;
liefert hier 0 und 0,006

SQL-Code:
select 0.100 * (12 / 100.000 * 0.5000) as a, 0.100 * (0.5000 / 100 * 12) as b from dual;
liefert hier 0,006 und 0,006

hä???

Da wird also "innendrinnen" irgendwie implizit gerundet auf die Zahl der da gerade (zufällig) anwesenden oder eben auch nicht anwesenden Nachkommastellen.

Oder anders ausgedrückt:

Wir haben hier Ganzzahl- und Nachkommazahlen.

Da wird eine Typkonvertierung gemacht, entweder auf Ganzzahl oder auf Nachkommazahl. Und dann wird da "irgendwie" entsprechend gerundet ;-)

Achso: Bevor ich es vergesse:

Die Ergebnisse mit einem Delphiprogramm über die ADO-Komponenten (s. o.) sind andere, als die über FlameRobin:

SQL-Code:
select 0.1 * (12 / 100 * 0.5) as a, 0.1 * (0.5 / 100 * 12) as b from dual;
liefert 0,00 und 0,00

SQL-Code:
select 0.1 * (12 / 100 * 0.500) as a, 0.1 * (0.500 / 100 * 12) as b from dual;
liefert 0,0000 und 0,0060

SQL-Code:
select 0.100 * (12 / 100.000 * 0.5000) as a, 0.100 * (0.5000 / 100 * 12) as b from dual;
liefert 0.0060000000 und 0.0060000

Upps :oops:

Moombas 12. Jun 2019 14:37

AW: MS SQL Genauigkeit in der Termauswertung
 
@Delphi.Narium: Kannst du mein Beispiel mit der Klammersetzung auch mal ausgeben und Posten (oder rein editieren)? Würde mich einfach mal interessieren.

Zitat:

Zitat von Delphi.Narium (Beitrag 1434459)
Die Ergebnisse mit einem Delphiprogramm über die ADO-Komponenten (s. o.) sind andere, als die über FlameRobin:

SQL-Code:
select 0.1 * (12 / 100 * 0.5) as a, 0.1 * (0.5 / 100 * 12) as b from dual;
liefert 0,00 und 0,00

SQL-Code:
select 0.1 * (12 / 100 * 0.500) as a, 0.1 * (0.500 / 100 * 12) as b from dual;
liefert 0,0000 und 0,0060

SQL-Code:
select 0.100 * (12 / 100.000 * 0.5000) as a, 0.100 * (0.5000 / 100 * 12) as b from dual;
liefert 0.0060000000 und 0.0060000

Upps :oops:

Interessant finde ich, das die Anzahl der Nachkommastellen im Ergebnis jedesmal der Summe der Nachkommastellen in der Rechnung Entspricht. Also sonst auch mal probieren (wo man auch immer die Stellen platziert, wenn man vorher wissen muss wie viele Nachkommastellen man haben muss finde ich das Suboptimal):

SQL-Code:
select 0.1 * (12 / 100 * 0.50) as a, 0.1 * (0.50 / 100 * 12) as b from dual;

hoika 12. Jun 2019 14:51

AW: MS SQL Genauigkeit in der Termauswertung
 
Hallo,

12/100.00 vielleicht?


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:32 Uhr.
Seite 1 von 4  1 23     Letzte » 

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz