Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Firebird und Numeric fields (https://www.delphipraxis.net/193370-firebird-und-numeric-fields.html)

MyRealName 21. Jul 2017 17:48

Datenbank: Firebird • Version: 3 • Zugriff über: UniDAC

Firebird und Numeric fields
 
Ich habe imme rmal wieder ein blödes Problem mit Firebird

Ich habe Felder in einer Warenwirtschaft für Preis und Menge, alle mit Numerics, da mir floats oft Probleme bereiten mit Menge = 0.000000024565, was technisch eine 0 ist, aber man ist da strikt bei FB :)
Bei Numerics (zum Bsp. 18.4) habe ich dann andere Probleme wie Feld1 (18,4) * Feld2 (18.4) ergibt Result = 18,8 und das wiederrum kann zu überläufen führen (in Kolumbien haben wir grosse Geldmengen, 3500 COP (kol. Peso) = 1 Euro, 1 Mrd. COP man grad so 300k euro

das einizge was ichs ehe ist alle immer casten wieder auf 18,4, jede zwischen-operation... geht das nicht besser ?

Helge

himitsu 21. Jul 2017 17:59

AW: Firebird und Numeric fields
 
In 18.4 passt z.B. folgende Zahl 12.345.678.901.234,5789 und das sind immerhin nur in etwa 3,5 Milliarden Euro. (bis zu 28 Mrd.€)
Wenn dir das nicht reicht, dann kannst du es auch problemlos als Nummeric(999999.4) speichern.

Numeric(18.4) würde aber zumindestens dem Typ Currency im Delphi entsprechen, falls man auch da problemlos rundungssicher arbeiten/rechnen will.


Zitat:

da mir floats oft Probleme bereiten mit Menge
Darum sollte man auch im Delphi bei sowas vielleicht besser mit Delphi-Referenz durchsuchenCurrency arbeiten und bei Floats niemals auf gleich/identisch Prüfen.

MyRealName 21. Jul 2017 18:54

AW: Firebird und Numeric fields
 
Numeric(9999,4) geht nicht, geht in firebird scheinbar "nur" bis 18.
Eigentlich wollte ich ja numeric(18.4) für alle Currency-Felder, aber jede mathematische Op in firebird erzeugt daraus ein 18,8... dann passen da nur noch 1.234.567.890,12345 rein, also man grad 310k euro in Pesos.

und das problem habe ich nicht in Delphi, osndern nur in Firebird. In Delphi kann cih mit Currency für geld arbeiten und bei Inventar-Mengen mit extended und CompareValue.

Lemmy 21. Jul 2017 19:05

AW: Firebird und Numeric fields
 
Zitat:

Zitat von MyRealName (Beitrag 1377210)
Eigentlich wollte ich ja numeric(18.4) für alle Currency-Felder, aber jede mathematische Op in firebird erzeugt daraus ein 18,8...


bei mir nicht.. welche Firebirdversion hast Du denn? Die 2.1 macht das problemlos mit:



Code:
CREATE TABLE Test (
test1 Numeric(18,4),
test2 Numeric(18,4),
test3 Numeric(18,4));


INSERT INTO test VALUES (2.5, 5, 0);

UPDATE test SET test3=Test1*test2;
Und selbst wenn das in neueren Firebird geändert wurde, was spricht denn gegen ein

Code:
Select cast(test1*test2 AS Numeric(18.4)) from test
Grüße

mensch72 21. Jul 2017 19:30

AW: Firebird und Numeric fields
 
mal unabhängig von der Frage, ob es real überhaupt "0,xx COP" gibt, stellt sich die Frage warum eine solche Software nicht intern und in der DB mit einer "passenden" normalisierten Einheit programmiert wird?

Wir arbeiten im Finanzbereich intern seit der Euro Einfühung quasi mit dem "USD Fixing zu diesem Zeitpunkt" für alles und jedes als unsere interne "UniversalExchangeUnit" abgekürzt "UEU".
Bei Zeiten speichern und rechnen wir nur in UTC... Wenn in Japan oder Kolumbien sich jemand was aktuell BTC mit 0,0000xxxxxx eingibt oder anzeigt, ist das nicht viel anders wie wenn er es für was wertvolle wie Gold XXXX,xxx tun würde.
(Wenn Kunden mit den Augen rollen, weil sie mit den internen Daten in unserer DB nix anfangen können, bekommen sie als Dienstleistung passende "ReadOnly" Views und können sich je nach Gusto dann an ihren "NullNullXvalues" oder "BigValues" erfeuen)

Klar ist das eine Konzeptfrage, aber bei sauberer Trennung von GUI<->DB<->BussinesLogic sollte das doch kein Problem sein. Dann reichen in der DB auch Numeric/BCD und in Delphi "Currency/FixComma".

Und Astronomen sowie Pysiker machen es doch auch so clever... die verrechnen normalisierte Werte und Einheiten getrennt und normalisieren zum Schluss nochmal das Ergebnis auf eine passende Basiseinheit mit sinnvoller Genauigkeit.
Das machten die schon mit Rechnenschiebern so und machen es auch heute mit Computern noch so... die versuchen garnicht erst eine Zahl im Wertebereich bis 10^ +18 auch noch mit einer Genauigkeit auf 10^ -18 zu definieren... die haben&nutzen entweder das eine oder das andere, und bleiben so immer in ihrer konstanten Genauigkeit (hier im Beispiel 18Stellen), egal ob tausend Stellen vor dem Komma, oder tausend Stellen hinter dem Komma.

MyRealName 21. Jul 2017 19:38

AW: Firebird und Numeric fields
 
Zitat:

Zitat von Lemmy (Beitrag 1377211)
Zitat:

Zitat von MyRealName (Beitrag 1377210)
Eigentlich wollte ich ja numeric(18.4) für alle Currency-Felder, aber jede mathematische Op in firebird erzeugt daraus ein 18,8...


bei mir nicht.. welche Firebirdversion hast Du denn? Die 2.1 macht das problemlos mit:



Code:
CREATE TABLE Test (
test1 Numeric(18,4),
test2 Numeric(18,4),
test3 Numeric(18,4));


INSERT INTO test VALUES (2.5, 5, 0);

UPDATE test SET test3=Test1*test2;
Und selbst wenn das in neueren Firebird geändert wurde, was spricht denn gegen ein

Code:
Select cast(test1*test2 AS Numeric(18.4)) from test
Grüße

http://www.firebirdfaq.org/faq79/

Zitat:

Here's an example: if you multiply 9.12 with 8.11 (both numeric(18,2)) you would get 73.9632. If Firebird would store that into numeric(18,2) datatype, we would lose 0.0032. Doesn't look much, but when you have complex calculations, you can easily loose thousands (dollars or euros). Therefore, the result is stored in numeric(18,4).

himitsu 21. Jul 2017 19:55

AW: Firebird und Numeric fields
 
SQL-Code:
A * B * C * D * E * F * G * H -- alles numeric(18.2)
ergibt dann also
SQL-Code:
numeric(18.16)
?

Ich hätte eher erwartet, dass hinten das raus kommt, was als "größter" Typ rein ging.

MyRealName 21. Jul 2017 20:07

AW: Firebird und Numeric fields
 
Zitat:

Zitat von himitsu (Beitrag 1377215)
SQL-Code:
A * B * C * D * E * F * G * H -- alles numeric(18.2)
ergibt dann also
SQL-Code:
numeric(18.16)
?

Ich hätte eher erwartet, dass hinten das raus kommt, was als "größter" Typ rein ging.

Ich auch, aber das ist, was bei firebird auf der Seite steht...

Mein Ansatz im MOment ist es, dass ich es händisch vielleicht selbst mache... alles mit 10.000 multiplizieren und in einem Bigint speichern und damit rechnen und dann alles durch 10.000 dividieren und dann in ein Numeric(18,4)

Lemmy 21. Jul 2017 22:41

AW: Firebird und Numeric fields
 
Zitat:

Zitat von MyRealName (Beitrag 1377214)
http://www.firebirdfaq.org/faq79/

Zitat:

Here's an example: if you multiply 9.12 with 8.11 (both numeric(18,2)) you would get 73.9632. If Firebird would store that into numeric(18,2) datatype, we would lose 0.0032. Doesn't look much, but when you have complex calculations, you can easily loose thousands (dollars or euros). Therefore, the result is stored in numeric(18,4).


ähm. ja.. Logisch. Technisch bedingt aber eine Multiplikation von Numeric(18,4) kein Ergebnis mit mehr Nachkommastellen. Das kann max. eine fachliche Anforderung sein, davon hast Du leider nix geschrieben. Und ja, es gibt Anwendungsfälle, bei denen man zwingend die Zwischenergebnisse auf 2 Nachkommastellen rundet.

hstreicher 22. Jul 2017 06:44

AW: Firebird und Numeric fields
 
Zitat:

Zitat von himitsu (Beitrag 1377215)
SQL-Code:
A * B * C * D * E * F * G * H -- alles numeric(18.2)
ergibt dann also
SQL-Code:
numeric(18.16)
?

Ich hätte eher erwartet, dass hinten das raus kommt, was als "größter" Typ rein ging.


ja, so kommt das raus , ist aber glaube ich SQL Standard
das Problem löst man mit einer Cast "Orgie" um die Overflows die sich bei längeren Berechnungen ergeben abzufangen

also
Code:
cast(cast(cast(a*b as numeric(18,4))*c as numeric(18,4))*d as numeric(18,4))


http://www.firebirdsql.org/file/comm..._datatypes.pdf


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:22 Uhr.
Seite 1 von 2  1 2      

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