Überlauf Schutz durch automatische reservierung



  • Guten Morgen Leute,

    ich möchte für ein aktuelles (stark unter- und überlaufs gefährdetes) Projekt eine Klasse so konzipieren, dass ich Zahlen (sowohl gleitkomma, als auch ganzzahl) so definieren kann, dass diese sich im Falle eines drohenden Speicherüberlaufs dynamisch mehr besorgen 😃 ...

    Beispielsweise Shorts, die sich, sollten sie zu hoch addiert werden, so viele Shorts holen (und die überstehenden Ziffern in die neuen reinschreiben), dass kein Überlauf eintreten kann... äh ach ja, die üblichen arithmetischen methoden sollten dann natürlich noch implementiert werden, als operator elementfunktionen oder als globale, mal schauen - ohne gleitkomma-ungenauigkeit, aber das kommt später.

    1. Geht sowas? ( gehen tut alles - ich präzisiere: Geht das unter 1000 zeilen?)
    2. Kann mir jemand einen Tipp (mehr will ich gar nicht) geben, in welche Richtung das ungefähr laufen könnte ? Welche Möglichkeiten habe ich ?

    Ich danke.



  • Schau mal bei www.generic-home.de vorbei. Dort gibt es unter anderem:

    "Eine Klasse für BCD Zahlen (Binary Coded Decimal) ermöglicht genaue dezimale Arithmetik für alle Arten von kommerziellen Anwendungen, die sich Rundungsfehler nicht leisten können. Eine Genauigkeit von 18 Stellen ist für einen Zahlenbereich zwischen 10E-63 und 10E+63 garantiert. Damit läßt sich die Staatsschulden aller Staaten der Welt auf den Pfennig genau ausrechnen."

    Wenn Du es lieber selbst machen möchtest, sind BCD - Zahlen auf jeden (meiner Meinung nach) Deine Lösung.



  • Nette Sache - zum Thema selbst machen: Kannst du nähere Infos zur Implementierung dieser Zahlen geben ? also jede ziffer wird binär dargestellt, soweit so klar. Wie er folgt die nachkomma implementierung ? Wie könnten (umriss) arithmetische aktionen implementiert werden ?



  • Jede Ziffer wird in einem Byte gespeichert. Um Platz zu sparen, kann man auch 2 Ziffern in einem Byte - also jeweils ein halbes Byte repräsentiert eine Ziffer - speichern.
    Implementierungsdetails kann ich Dir da auch nicht geben.
    Ich habe sowas mal mit einem anderen Ansatz begonnen, indem ich den Vorkommateil und den Nachkommateil getrennt in einem int - Wert gespeichert habe.
    Zusätzlich hatte ich noch einen bool für das Vorzeichen und einen weiteren int - Wert für die Anzahl der Nachkommastellen - so daß zB der Wert 52,0034 so abgespeichert wurde:

    int vk = 52
    int nk = 34
    int nkstellen = 4
    bool negativ = false

    Das Rechnen damit war etwas holperig wegen der seltsamen Speicherung des Nachkommaanteils (ich hatte keine bessere Idee), aber Addition und Subtraktion hatte ich wohl implementiert (Überladen der Operatoren + bzw. -).
    Ein paar sinnvolle Konstruktoren dazu ...
    Multiplikation dürfte auch kein Problem sein, denke ich, über Division habe ich mir noch keine Gedanken gemacht.
    Für meine damalige Problemstellung genügte Addition und Subtraktion - ich hatte vorher float - Werte und die taugen nicht für Anwendungen, die mit Beträgen hantieren.



  • Ja, die Trennung von Vor- und Nachkommastellen war auch meine erste Überlegung - ich dachte nur es gäbe eine hübsche lehrbuch, standard lösung ... aber danke!

    Wenn ich das jetzt noch so hinkriege, dass ich zu den Zahlen irgendwie gültigkeits bereiche angeben könnte, bei deren überschreiten automatisch mehr reserviert wird, wäre ich ausnahmsweise sogar mal glücklich ... 😉



  • Du hast damit 9 Vorkommastellen und 9 signifikante Nachkommastellen, wobei Du tatsächlich viel mehr Nachkommastellen haben kannst:

    vk = 123456789
    nk = 987654321
    nkstellen = 15

    ergibt: 123456789,000000987654321

    das sollte für normale Anwendungen, die mit Währungen, Beträgen hantieren doch genügen?!
    Für wissenschaftliche Anwendungen wiederum eignen sich ja float/double sowieso besser.

    Ansonsten gibt es bei einigen modernen Compilern doch auch 64bit-Integer - Werte, die Du Dir sonst zur Not selbst zusammenstricken kannst - dann wird es halt noch einmal aufwendiger.

    Alternativ kannst Du ja mal über das BCD-Format nachdenken ... ein Byte je Ziffer für den Anfang - irgendwie muß das ja auch gehen, ich hab mir da noch keine ernsthaften Gedanken drüber gemacht.
    Oder Du holst Dir den Code von www.generic-home.de und schaust Dir mal deren Schnittstelle an ... vielleicht ergeben sich daraus ein paar Anregungen.

    Auf jeden Fall viel Spaß bei den weiteren Forschungen!



  • Hab gerade noch mal nachgesehen, Du kannst dort den Source-Code downloaden und nachsehen, wie es dort gemacht wird ...



  • Belli schrieb:

    Hab gerade noch mal nachgesehen, Du kannst dort den Source-Code downloaden und nachsehen, wie es dort gemacht wird ...

    ah, super danke ! sowas brauchte ich ...



  • Hallo Leute,

    nachdem ich eine ganze Menge anderes Krams gemacht habe, habe ich soeben versucht mir die generic++ BCD-Klasse zu besorgen und zu benutzen - versucht wohlgemerkt :D. Es funktioniert soweit alles und die Klasse scheint ein äußerst mächtiges Tool zu sein, nur leider kann ich nichts mehr kompilieren, da alles voller "ungelöster externen"ist. JEde benutzte Elementfunktion wird als "unresolved external" in meiner .obj datei angezeigt. Da ich immer noch nicht so richtig weiß, was ich in so einem falle tun soll, frage ich euch einfach mal. Muss man spezielle Dinge beachten, wenn man eine solche Bibliothek, wie die Generic++ verwendet, beachten, was den Linker angeht ?



  • Ja, das muss man. Ich kenne mich mit deiner konkreten Bibliothek nicht aus, aber du musst wahrscheinlich erstmal die Bibliothek selber kompilieren und dann (je nach Compiler/Linker unterschiedlich) deinen Compiler/Linker dazu bringen, dagegen zu linken.

    Felix



  • Phoemuex schrieb:

    ... aber du musst wahrscheinlich erstmal die Bibliothek selber kompilieren...

    naja, also es gibt einen include-Ordner und in der Hilfe steht nur davon, dass man einen bestimmte .h-Datei #includen soll. Das habe ich gemacht und die IDE (borland builder) schluckt die Klasse auch problemlos (Tool Tipps werden zu allen Elementfunktionen korrekt angezeigt). Woran erkennt man, dass man bestimmte Bibliotheken kompilieren muss ? Bei der Boost funktionierte es auch immer so (bisher warens aber auch nur die hübschen shared_ptr's :D).

    Phoemuex schrieb:

    ... und dann (je nach Compiler/Linker unterschiedlich) deinen Compiler/Linker dazu bringen, dagegen zu linken.

    Ähm - also als #include Pfad ist das entsprechende Verzeichnis angegeben ...
    😞



  • mhh.. ok, ich finde den Fehler (mal wieder) nicht... Kennt sich jemand mit dieser Bibliothek aus oder allgemein, was man da tut (falls es irgendwelche standard Fehler gibt?). Ich kenne mich leider mit der Einbindung von solchen externen Sachen auch nicht so gut aus.

    Ich bin mittlerweile so weit, dass ich herausgefunden habe, dass es an der Bibliothek (also an meiner Vorgehensweise sie einzubinden) liegt, warum es nicht funktioniert.

    Denn wenn ich ein "leeres" Projekt erstelle und darin mal eine G_BCD Instanz erschaffe, hagelt es ebenfalls "ungelöste externe".
    In der Beschreibung der Klasse steht:

    Data type that provides precise decimal floating point arithmetic. More...

    #include <gbcd.h>

    List of all members.
    Public Methods
    .
    .
    .
    blabla

    was ich mal so interpretiert habe, dass man diese gbcd.h einbinden soll - das habe ich getan.

    #include <vcl.h>
    #include <gbcd.h>
    #pragma hdrstop
    
    #include "Unit2.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm2 *Form2;
    //---------------------------------------------------------------------------
    __fastcall TForm2::TForm2(TComponent* Owner)
    	: TForm(Owner)
    {
    	G_BCD s;
    	int g = s.toInt();
    }
    

    Das gibt dann:

    [Linker Fehler] Error: Ungelöste externe 'G_BCD::G_BCD()' referenziert von C:\DOKUMENTE UND EINSTELLUNGEN\ROOT\EIGENE DATEIEN\BORLAND STUDIO-PROJEKTE\DEBUG_BUILD\UNIT2.OBJ
    [Linker Fehler] Error: Ungelöste externe 'G_BCD::toInt() const' referenziert von C:\DOKUMENTE UND EINSTELLUNGEN\ROOT\EIGENE DATEIEN\BORLAND STUDIO-PROJEKTE\DEBUG_BUILD\UNIT2.OBJ
    

    Grrr... 😡

    Nebenbemerkung: Bei der Compilation ist mir aufgefallen, dass wenn man fstream mit includiert es namenskonflikte mit der gbcd gibt - das habe ich aber gelöst, indem ich die stream einfach nicht mehr include oder eins von beiden in einen namespace gesteckt habe - aber das nur nebenbei.



  • Ok, gegessen- ich weiß jetzt zumindest, wie und was ich compilieren muss - aber diese Frage stelle ich besser in einem neuen Thread, in einem anderen Unterforum



  • Sehrwahrscheinlich hast du eine benötigte Bibliothek (.lib-Datei, Header sind keine Bibliotheken) nicht mitgelinkt.

    Floyd schrieb:

    Nebenbemerkung: Bei der Compilation ist mir aufgefallen, dass wenn man fstream mit includiert es namenskonflikte mit der gbcd gibt - das habe ich aber gelöst, indem ich die stream einfach nicht mehr include oder eins von beiden in einen namespace gesteckt habe - aber das nur nebenbei.

    Wie wärs, wenn man fstream einfach im Namensraum std lassen würde?


Anmelden zum Antworten