Delphi-PRAXiS
Seite 2 von 2     12   

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)

IBExpert 22. Jul 2017 10:23

AW: Firebird und Numeric fields
 
innerhalb zB der Euro Welt oder beim US$ kommt man mit fest defininerten 2 Nachkommastellen eigentlich schon ganz gut klar im Bereich Währungsangaben, bei Mengenangaben ist das je nach Branche und Mengeneinheit aber schon ganz anders. Im Bereich industrieller Kalkulation sind da schon gerne mal 3-4 Nachkommastellen erforderlich, daher ist eigentlich Numeric(18,4) schon der passende Typ (der war aber pysikalisch im Dialekt 3 in einem Bigint gespeichert.

Vielleicht hilft es dir aber, einfach mal auch in Firebird den Typ "DOUBLE PRECISION" zu nehmen, dessen Verhalten ziemlich identisch zum Double in Delphi ist.
Um den dann mit definierter Anzahl Nachkommastellen darzustellen, kannst du dir ja bei Firebird 3 eine eigene Stored function bauen, die deine Währungseinstellung berücksichtigt oder konstant einfach mit ROUND() oder cast arbeiten

Olli73 22. Jul 2017 11:58

AW: Firebird und Numeric fields
 
Ich hatte mir mal per UDF Funktionen angelegt, die das casten vereinfachen:

roundC4 = Runden auf 4 Nachkommastellen
CuToDp = Currency to Double Precision
etc.

Aussehen tut das dann so:

Code:
B_SPROZ  = case when B_SND=0 then 0 else roundc4(cutodp(1200)/cutodp(B_SND)) end,
oder so:

Code:
B_SAFAWJ = case when
              B_SRND=0 
            then
              roundc2( cutodp(0) + cutodp(B_ZUGWJ) )
            else
              case when
                B_WJAHR=B_IJAHR
              then
                roundc2( cutodp(B_ZUGWJ)*cutodp(13-B_ZUGMON)/cutodp(B_SRND) )
              else
                roundc2(   
                  case when
                    B_SRND<=12
                  then
                    cutodp(B_SRWVJ)*cutodp(B_AWERT-B_ABGWJ)/cutodp(B_AWERT)
                    + cutodp(B_ZUGWJ)
                  else
                    cutodp(B_SRWVJ)*cutodp(B_AWERT-B_ABGWJ)/cutodp(B_AWERT) * cutodp(12)/cutodp(B_SRND)
                    + cutodp(B_ZUGWJ)*cutodp(13-B_ZUGMON)/cutodp(B_SRND-B_ZUGMON+1)
                  end
                )
              end
            end,

Edit: Mit Oracle z.B. gibt es diese Probleme nicht.

MyRealName 24. Jul 2017 14:35

AW: Firebird und Numeric fields
 
Zitat:

Zitat von IBExpert (Beitrag 1377228)
Vielleicht hilft es dir aber, einfach mal auch in Firebird den Typ "DOUBLE PRECISION" zu nehmen, dessen Verhalten ziemlich identisch zum Double in Delphi ist.
Um den dann mit definierter Anzahl Nachkommastellen darzustellen, kannst du dir ja bei Firebird 3 eine eigene Stored function bauen, die deine Währungseinstellung berücksichtigt oder konstant einfach mit ROUND() oder cast arbeiten

Hat Double Precicion nicht das gleiche Problem wie die anderen "natürlichen" floats, dass 0 nicht gleich 0 ist ?
Eins der probleme, welche ch immer wieder habe ist das physikalisch meine Inventarmenge 0 ist, aber beim Berechnen in firebird sowas wie 0.00000046784345 rauskommt, und das dann ich Berechnungen zu riesig grossen zahlen führt, die einen überlauf produzieren..

p80286 24. Jul 2017 17:25

AW: Firebird und Numeric fields
 
Der Vorschlag von mensch72 scheint mir doch sehr beachtenswert, da auch nach meiner Erfahrung Währungen mit großen Zahlen im allg. auch auf Nachkommastellen verzichten. Interessant wird es dann bei 100/3. Willst du als Ergebnis 33.33 und 0.01 für die Kaffeekasse oder 33.34 und 0.02 als Wertschöpfung? Je nach Rechenweg kann man den Fehler verringern aber ganz ohne Rundungsfehler geht es nicht. Und darüber solltest Du Dir im Klaren sein, und ggf. dies auch mit deinen Kunden/Chefs kommunizieren.

Gruß
K-H

IBExpert 24. Jul 2017 23:18

AW: Firebird und Numeric fields
 
Zitat:

Zitat von MyRealName (Beitrag 1377351)
...
Hat Double Precicion nicht das gleiche Problem wie die anderen "natürlichen" floats, dass 0 nicht gleich 0 ist ?
Eins der probleme, welche ch immer wieder habe ist das physikalisch meine Inventarmenge 0 ist, aber beim Berechnen in firebird sowas wie 0.00000046784345 rauskommt, und das dann ich Berechnungen zu riesig grossen zahlen führt, die einen überlauf produzieren..

inventarmengen bei Zählbaren Artikel sind sicherlich ganzzahlig, bei anderen Mengeneinheiten kann das aber ganz anders aussehen, Schrauben werden ja trotzdem gerne gewogen statt gezählt, weil zählen Schwachsinn ist, Draht wird in Meter gezählt oder auch gewogen, taucht aber in cm oder mm in Stücklisten auf usw.

Das Problem ist dir sicherlich bekannt.

Aus meiner hat aber der Wert 0 erst mal auch den exakten Wert 0, aber wenn 0 aus einer anderen als einer konstanten Quelle kommt, kann das zwar wie 0 aussehen, aber bei den Nachkommastellen ganz hinten wie du sagst anders aussehen. Trotzdem arbeitet der Double Precision eigentlich ganz sauber (zumindest in Firbeird und bitte niemals mit dem Typ Float arbeiten, der taugt nix).

Für technischen Kram nehm ich ganz gerne Double Precision, für kaufmännischen Kram Numeric, es gibt aber nicht den Typ für alles (und das weiss ich schon seit der Euroumstellung, da hat auch diverse Software eher ungefähre Schätzwerte ermittelt, wenn der Eurofaktor mit größeren Zahlen ermittelt wurde).

Mein Lieblingsbeispiel aus Schulungen, das den Unterschied von Numeric(15,2) im Dialekt 1 (dort gepeichert als Double Precision) und Numeric(15,2) im Dialekt 2 (dort gespeichert als BigInt, also Int64).

Deine Software wird für die Abrechnung einer Konditorei benutzt und die stellt Torten her, die 10 Euro kosten. Aufgteilt ist 3 Stücke ermittelt deine Software nun einen Preis von 3,33 € pro Stück (im Double Precision wird aber eigentlich 10/3 gespeichert, Ergebnis also eigentlich 3,333333333333 usw.) Nun kommt Oma Schmidt in den Laden, kauft 3 Stück Torte zu je 3,33 € und deine Kassensoftware ermittelt auf Basis vom Double Precision als Summe 10 €. Viel Spass bei der Diskussion mit Oma Schmidt.

Wer seinen Tankwart mal ärgern will: einfach mal beim Tanken noch ein paar andere Artikel kaufen, (zB eine Zeitschrift, weil die 7% Steuer hat) und sich danach mal die Nachkommastellen aller Produkte anschauen und auch bei den Teilsummen der unterschiedlichen Steuern anschauen und zusammenrechnen. Es kommt nicht selten vor, das die Zahlen da zusammengerechnet nicht zu dem passen was man am Ende zahlen soll. Das liegt u.a. an der 3. Nachkommastelle bei den Spritpreisen. da ist auch scheinbar manche Kassensoftware überfordert. Dem armen unterbezahlten Menschen an der Kasse ist das aber ziemlich sicher scheissegal.

Hier noch ein Code Beispiel für Firebird, an dem man sehen kann, das Double ganz gut arbeitet:

Code:
execute block
returns
(dval double precision,
txt varchar(80))
as
declare variable v1 double precision;
declare variable v2 double precision;
begin
  v1=0;
  v2=3.141592653589793;
  dval=v1*v2;
  txt=dval;
  suspend;
  v1=1;
  v2=3.141592653589793;
  dval=v1*v2;
  txt=dval;
  suspend;
  v1=1.0001;
  v2=0.0001;
  dval=v1*v2;
  txt=dval;
  suspend;
end

result in IBExpert (im Grid wäre DVAL auf 3 stellen gerundet, beim Export aber nahezu komplett)

DVAL                    TXT
0                    0.0000000000000000
3,14159265358979    3.141592653589793
0,00010001            0.0001000100000000000


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:08 Uhr.
Seite 2 von 2     12   

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