<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
  <title></title>
</head>
<body bgcolor="#ffffff" text="#000000">
Danke f&uuml;r die ausf&uuml;hrliche Info.<br>
Da bleibt mir halt nichts anderes &uuml;brig, als die Windows-Typen
nachzuimplementieren.<br>
Eingentlich geht's mir auch gar nicht so um die Brechnungen als um die
verlustfreie &Uuml;bertragung von Daten.<br>
Ich implementiere zur Zeit einen platformunabh&auml;ngigen VARIANT, der
unter anderem auch die Typen CY und DECIMAL aufnehmen muss.<br>
Dabei M&uuml;ssen Arrays von Werten (Prozessdaten) verschiedener Typen, die
als VARIANT bei DCOM oder als anyType bei SOAP &uuml;bertragen werden<br>
auch auf Linux entsprechend in einen eigenen VARIANT aus unserer C++
API gewandelt werden.<br>
Interpretieren muss ich die Strukturieren nur soweit, dass ich die
Typen bei einem VariantChangeType-Aufruf in anderen Typen umwandeln
kann.<br>
Zum Beispiel bei der Darstellung als String.<br>
Andere arithmetische Funktionen brauche ich zum Gl&uuml;ck nicht.<br>
<br>
Z.Info die Windows-Definitionen aus wtypes.h.<br>
DECIMAL: hier betr&auml;gt der Wert Lo64 * 10 ^ -scale<br>
&Uuml;ber das sign in signscale bin ich mir noch nicht klar, da der Wert nur
in eine Richtung skaliert werden kann soweit ich gesehen habe.<br>
typedef struct tagDEC {<br>
&nbsp;&nbsp;&nbsp; USHORT wReserved;<br>
&nbsp;&nbsp;&nbsp; union {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BYTE scale;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BYTE sign;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; USHORT signscale;<br>
&nbsp;&nbsp;&nbsp; };<br>
&nbsp;&nbsp;&nbsp; ULONG Hi32;<br>
&nbsp;&nbsp;&nbsp; union {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct {<br>
#ifdef _MAC<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ULONG Mid32;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ULONG Lo32;<br>
#else<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ULONG Lo32;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ULONG Mid32;<br>
#endif<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ULONGLONG Lo64;<br>
&nbsp;&nbsp;&nbsp; };<br>
} DECIMAL;<br>
<br>
CY:&nbsp; hier ist die Precision konstant<br>
z.B.: Wert = int64 * 10 ^ -4<br>
typedef union tagCY {<br>
&nbsp;&nbsp;&nbsp; struct {<br>
#ifdef _MAC<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Hi;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long Lo;<br>
#else<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned long Lo;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Hi;<br>
#endif<br>
&nbsp;&nbsp;&nbsp; };<br>
&nbsp;&nbsp;&nbsp; LONGLONG int64;<br>
} CY;<br>
<br>
Christian Stimming wrote:
<blockquote cite="mid200411131430.57403.stimming@tuhh.de" type="cite">
  <pre wrap="">Am Freitag, 12. November 2004 11:03 schrieben Sie:
  </pre>
  <blockquote type="cite">
    <pre wrap="">ich habe da mal eine Frage zu fixed precision data types unter Linux.
Unter Windows gibt es da den DECIMAL type, der eben speziell f&uuml;r
finanzielle Berechnungen eingesetzt wird, damit man im Gegensatz zu
Floating-Points immer die gleiche Precision hat.
Was gibt es da vergleichbares unter Linux?
Bei GnuCash wird so was ja auch bestimmt eingesetzt.
    </pre>
  </blockquote>
  <pre wrap=""><!---->
Es gibt unter Linux/Posix-Unix keinen allgemein verwendeten Typen, der sowas 
macht!!!

Man mu&szlig; sich also in jeder Software selber aus den Basistypen eine passende 
structure zusammenbauen und die dann verwenden. Die Frage ist also v&ouml;llig 
berechtigt und ich habe kurzerhand mal nachgesehen, was die ganzen 
OpenSource-Programme so haben:

GnuCash
-----------
In Gnucash war seinerzeit (Mitte 2000) die Entscheidung getroffen worden, da&szlig; 
man "rationale Zahlen" benutzt, also einen ganzzahligen Z&auml;hler und Nenner, 
siehe src/engine/gnc-numeric.h:

struct _gnc_numeric {
  gint64  num;
  gint64  denom;
};

siehe auch <a class="moz-txt-link-freetext" href="https://cvs.gnucash.org/cgi-bin/cvsweb.cgi/gnucash/src/engine/">https://cvs.gnucash.org/cgi-bin/cvsweb.cgi/gnucash/src/engine/</a>
gnc-numeric.h?rev=1.23 -- unbedingt den CVS-HEAD branch verwenden und nicht 
die Version im 1.8.x-Branch, da in HEAD sehr viel mehr Dokumentation drin 
ist.

[Der Typ "gint64" kommt aus der glib (der glib von Gnome, nicht zu verwecheln 
mit der glibc), weil innerhalb der glib f&uuml;r die unterschiedlichen Plattformen 
die passenden typedefs gesetzt werden, so da&szlig; die Applikation sich bei gint64 
darauf verlassen kann, da&szlig; das &uuml;berall 64 bits sind. Aber das nur am Rande.]

In Gnucash sind wir also zu rationalen Zahlen gegangen (und der code darf 
gem&auml;&szlig; GPL gerne woanders weiterverwendet werden), aber wahrscheinlich war das 
ein overkill. Fix-Point Zahlen, also etwas Ganzzahliges mit fester 
Komma-Position, w&auml;ren wahrscheinlich in der Implementierung wesentlich 
einfacher gewesen. Nichtsdestotrotz m&uuml;sste man auch dabei eben alle 
arithmetischen Operationen f&uuml;r den neuen Typ einbauen und dabei f&uuml;r alle 
M&ouml;glichkeiten bei Rundungen sich die Auswahlm&ouml;glichkeiten &uuml;berlegen (also ob 
die zus&auml;tzlichen Nachkommastellen beim Multiplizieren nachher gerundet werden 
oder nicht etc). Und in der Implementierung w&auml;re ich nicht auf Anhieb so 
sicher, wie genau man das machen w&uuml;rde -- da man ja Bin&auml;rzahlen hat, w&auml;re es 
mit der einfachen Angabe "Nachkommastellen zur Basis 10" ja nicht erledigt, 
denn die gespeicherte Ganzzahl ist ja eine Ganzzahl zur Basis 2. Wie auch 
immer. In Gnucash gibts halt die Br&uuml;che mit einer hoffentlich vollst&auml;ndig 
richtigen Implementierung und die verwenden wir nun mal.

KMyMoney
-------------
Tja, offensichtlich haben die Kollegen dort das mit der GPL bereits ganz 
richtig verstanden :-) . Im Februar 2004 haben die n&auml;mlich ihrerseits den 
Umstieg von "double"-Werte zu ganzzahligen Werten gemacht, und sie haben dazu 
genau den GnuCash-Code aus gnc-numeric.h/c r&uuml;berkopiert und in eine C+
+-Klasse umgeschrieben. Wenn du also so eine Implementation mit rationalen 
Zahlen in C++ suchst, dann findest du die in kmymoney2, Klasse MyMoneyMoney 
in mymoneymoney.h.

Grisbi
------
Die Herren von der Gtk2-Konkurrenz dagegen sind noch dabei stehengeblieben, 
da&szlig; die Finanz-Werte als "double" gespeichert werden. Denen steht der Umstieg 
also noch bevor -- aber vorher m&uuml;ssten die sich eh noch von der franz&ouml;sischen 
Sprache im Quelltext l&ouml;sen...

QBankManager

Die einfache Applikation QBankManager, die ja nur zum schnellen Verwalten des 
HBCI-Zugangs dienen soll, benutzt intern ebenfalls nur "double"-Werte (aus 
AB_VALUE). F&uuml;r den Import/Export von Daten sind "double"s wohl auch ok, denn 
Rundungsfehler bekommt man ja erst bei arithmetischen Operationen mit vielen 
dieser Werte (also z.B. beim laufenden Saldo eines Kontos).

Gru&szlig;

Christian Stimming



  </pre>
</blockquote>
<br>
<br>
<div class="moz-signature">-- <br>
mit freundlichen Gr&uuml;&szlig;en / best regards<br>
<br>
<b>Gerhard Gappmeier</b><br>
ascolab GmbH - automation system communication laboratory<br>
Tel.: +49 9131 691 123<br>
Fax: +49 9131 691 128<br>
Web: <a class="moz-txt-link-freetext" href="http://www.ascolab.com">http://www.ascolab.com</a><br>
GPG-Key: <a class="moz-txt-link-freetext" href="http://www.ascolab.com/pgp/gerhard.asc">http://www.ascolab.com/pgp/gerhard.asc</a><br>
</div>
</body>
</html>