BigDecimal - Include

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
CSHW89
Beiträge: 489
Registriert: 14.12.2008 12:22

BigDecimal - Include

Beitrag von CSHW89 »

BigDecimal - Include
Unicode, 32-Bit

So, habs ja Stargate versprochen, hier nun meine Include zum Thema unendlich große und genaue Decimalzahlen.
(Vergleich: http://www.purebasic.fr/german/viewtopi ... =8&t=19344)

Ein paar Anmerkungen dazu:
- Hab mich entschieden, keinen Speicher zu allocieren. Der Benutzer muss die Adresse als Parameter angeben, wo das Ergebnis gespeichert werden soll. Das sollte eine Variable mit dem Typ 'BigDecimal' sein (siehe auch Beispiel unten).
- Die Adresse des Ergebnisses kann die gleiche sein, wie einer der anderen Parameter.
- Der Parameter 'digits' kann in den meisten Fällen angegeben werden. Er limitiert die Berechungszeit und den gebrauchten Speicher. Das Ergebnis ist dann aber nicht mehr genau. Bei den Funktionen 'exp' und 'log' muss 'digits' angegeben werden.
- Falls 'digits' angegeben wird, wird gerunden. Wie gerundet wird, kann man selbst entscheiden (BDRoundMode).

So hier jetzt noch ein Beispiel:

Code: Alles auswählen

Define.BigDecimal bda, bdb, result

BDFromQuad(2947, bda)
BDFromString("0.000000000000000001", bdb)
BDAdd(bda, bdb, result)
Debug BDStr(result)
Debug BDStr(result, 10)

BDFromString("10", bda)
BDFromString("3", bdb)
BDDiv(bda, bdb, result, #Null, 200)
Debug BDStr(result)

BDFromString("1", bda)
BDExp(bda, result, 200)
Debug BDStr(result)

BDFromString("150", bda)
BDLog(bda, result, 200)
Debug BDStr(result)

BDFromDouble(-Infinity(), bda)
BDExp(bda, result, 20)
Debug BDStr(result)

BDFromString("12.74", bda)
BDFromString("12.75", bdb)
Debug BDStr(bda, 1)
Debug BDStr(bdb, 1)

BDRoundMode(#BDRoundHalfUp)

BDFromString("12.74", bda)
BDFromString("12.75", bdb)
Debug BDStr(bda, 1)
Debug BDStr(bdb, 1)
Und hier der Link:
http://cshw89.mevedia.de/BigDecimal.pb

Freu mich auf Kritik, Anregungen ect., blablub....

mfg kevin
Zuletzt geändert von CSHW89 am 22.04.2014 00:33, insgesamt 6-mal geändert.
Bild Bild Bild
http://www.jasik.de - Windows Hilfe Seite
padawan hat geschrieben:Ich liebe diese von hinten über die Brust ins Auge Lösungen
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6999
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: BigDecimal - Include

Beitrag von STARGÅTE »

Tachchen,

bin gerade dabei alles auszutesten
Hier mal n kleiner Fehler:
Bei BDFromDouble() verwendest du IsInfinity(), dass ist jedoch nur für Floats !!! damit kann man keine hohen Doubles übergeben

Ich finde aber interessant das deine proceduren schneller sind, obwohl die eigentlich eine "sinnlose" aktion machst:
CopyArray(help(), *result\man())

Das frist doch Zeit .. Wieso speicherst du die errechneten Werte nciht gleich in der neuen Zahl ab ?
Denn auch wenn das ergebnis ich die gleiche Zahl kommt, wie eine die übergeben würde, wird beim errechnen ja est das Feld ausgelesen udn dann erneuert, sollte also kein Fehler verursachen ...


EDIT:

Ein großen Problem gibs jedoch bei erreichen einer Potenz:

Code: Alles auswählen

Procedure BDPow(*a.BigDecimal, *b.BigDecimal, *c.BigDecimal, d)
  BDLog(*a, *c, d)
  BDMul(*b, *c, *c, d)
  BDExp(*c, *c, d)
EndProcedure
Wenn man da nur 10^10 berechnen lassen will, wirds entweder ungenau, oder dauert lange.
Da solltest du unbedingt noch n alternative einauen für Ganzzahlige Exponenten ...

Auch zum wurzelziehen, wäre das heron-Verfahren schneller.
Die EXP-Log variante wird nur schneller wenn der WurzelExponent groß ist.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
CSHW89
Beiträge: 489
Registriert: 14.12.2008 12:22

Re: BigDecimal - Include

Beitrag von CSHW89 »

STARGÅTE hat geschrieben:Hier mal n kleiner Fehler:
Bei BDFromDouble() verwendest du IsInfinity(), dass ist jedoch nur für Floats !!! damit kann man keine hohen Doubles übergeben
ist gefixed
STARGÅTE hat geschrieben:Ich finde aber interessant das deine proceduren schneller sind, obwohl die eigentlich eine "sinnlose" aktion machst:
CopyArray(help(), *result\man())

Das frist doch Zeit .. Wieso speicherst du die errechneten Werte nciht gleich in der neuen Zahl ab ?
Denn auch wenn das ergebnis ich die gleiche Zahl kommt, wie eine die übergeben würde, wird beim errechnen ja est das Feld ausgelesen udn dann erneuert, sollte also kein Fehler verursachen ...
tja, doch. sagen wir mal bei der multiplikation. die hab ich mit der schrichtichen multiplikation, wie in der schule, realisiert. dort braucht man auch zum schluss (also ganz vorne) noch beide operanten komplett beim rechnen.
STARGÅTE hat geschrieben:EDIT:
Ein großen Problem gibs jedoch bei erreichen einer Potenz:
Code:
Procedure BDPow(*a.BigDecimal, *b.BigDecimal, *c.BigDecimal, d)
BDLog(*a, *c, d)
BDMul(*b, *c, *c, d)
BDExp(*c, *c, d)
EndProcedure

Wenn man da nur 10^10 berechnen lassen will, wirds entweder ungenau, oder dauert lange.
Da solltest du unbedingt noch n alternative einauen für Ganzzahlige Exponenten ...

Auch zum wurzelziehen, wäre das heron-Verfahren schneller.
Die EXP-Log variante wird nur schneller wenn der WurzelExponent groß ist.
habs auch schon gemerkt, wollte eigentlich 'Pow' auch bereitstellen. hab aber gemerkt, dass das nicht so ganz das wahre ist, werd mich die nächsten tage damit beschäftigen.
STARGÅTE hat geschrieben:Ich finde aber interessant das deine proceduren schneller sind
:mrgreen: :mrgreen:

lg kevin
Bild Bild Bild
http://www.jasik.de - Windows Hilfe Seite
padawan hat geschrieben:Ich liebe diese von hinten über die Brust ins Auge Lösungen
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6999
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: BigDecimal - Include

Beitrag von STARGÅTE »

Aber von der Speed her, werden wir wohl immer Schlusslicht bleiben ...

EXP(1000) mit 100 Nachkommastellen, da "zuckt" Mathematicer nicht mal.
Bei mir (mit errechnetenm e und Power() ) dauert es 4 Sekunden
Und bei dir dauert das 8 Sekunden mit Exp()
Immerhin liefert es bei uns beiden die gewünschte genauigkeit ^^ :allright:


Ich habe mich übrignes dazu entschlossen, weiter auf dem "Schulweg" zu fahren, also so wenig näherungsverfahren, wie es geht.
Das macht zwar einiges langsammer, dafür habe ich fast überall unendliche genauigkeit!
Somit soltle gesichert sein, das unsere Includes sich unterscheiden.


Trotzdem würde ich gerne auch von den Memorys wegkommen und die Variable-Variante "kopieren" (hoffe du hast nix dagegen ^^), gleich verbunden mit dem bei mir angesprochenen Interface ...


Zur Multiplikation, jo da habe ich auch n Hilfe-Array, ich meinte ja nur bei Addition ...
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
CSHW89
Beiträge: 489
Registriert: 14.12.2008 12:22

Re: BigDecimal - Include

Beitrag von CSHW89 »

STARGÅTE hat geschrieben:Ich habe mich übrignes dazu entschlossen, weiter auf dem "Schulweg" zu fahren, also so wenig näherungsverfahren, wie es geht.
Das macht zwar einiges langsammer, dafür habe ich fast überall unendliche genauigkeit!
Somit soltle gesichert sein, das unsere Includes sich unterscheiden.
also ehrlich gesagt, weiß ich nicht so ganz, was du damit meinst. wenn du damit auf die 'div'-methode ansprichst, ich hatte ja erklärt, wie ich sie umgesetzt hab. ich sagte ja, ich berechne nährungsweise das ergebnis, damits schneller geht, es wird aber dann korrigiert, somit hat es die gewünschte genauigkeit, und wenn man so will, auch eine unendliche genauigkeit. wenn dies nicht so wäre, würde 'exp' auch nicht das gewünschte ergebnis liefern. das tuts aber, wenn man für 'digits' 1000 übergibt, sind auch alle 1000 (oder sagen wir 998) ziffern GENAU richtig.
STARGÅTE hat geschrieben:Trotzdem würde ich gerne auch von den Memorys wegkommen und die Variable-Variante "kopieren" (hoffe du hast nix dagegen ^^), gleich verbunden mit dem bei mir angesprochenen Interface ...
klar, hab ich nix gegen, kannste ruhig machen. ich hatte ja auch nur die idee, weil ja arrays in structuren jetzt möglich sind. sonst wäre das ja so nicht machbar.

lg kevin
Bild Bild Bild
http://www.jasik.de - Windows Hilfe Seite
padawan hat geschrieben:Ich liebe diese von hinten über die Brust ins Auge Lösungen
Benutzeravatar
CSHW89
Beiträge: 489
Registriert: 14.12.2008 12:22

Re: BigDecimal - Include

Beitrag von CSHW89 »

So hab eine kleine Änderung bei 'Log' vorgenommen. Die Funktion ist jetzt ca. 2000% schneller (ich glaub sogar noch schneller) als die alte Version. Downloadlink am Anfang.

lg kevin
Bild Bild Bild
http://www.jasik.de - Windows Hilfe Seite
padawan hat geschrieben:Ich liebe diese von hinten über die Brust ins Auge Lösungen
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Re: BigDecimal - Include

Beitrag von Helle »

@CSHW89: Schau mal Deine Subtraktion an:

Code: Alles auswählen

  66666666666665487986458484884684145737458469659244125252362634719113453253487793
-                                             734769847345737373711118058795087095
---------------------------------------------------------------------------------
  66666665666665486986458483884684144737458468924474277906625260007995394458400698  Dein Ergebnis
  66666666666665487986458484884684145737458468924474277906625261007995394458400698  Mein Ergebnis
Da meine heißgeliebten BCD´s in meinem Calculator von einem 64-Bit-OS nicht mehr unterstützt werden, habe ich mal ein wenig mit SSE (Add, Sub) gespielt und Deinen Code zum Ergebnis-Vergleich benutzt.

Gruß
Helle
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6999
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: BigDecimal - Include

Beitrag von STARGÅTE »

Das sieht sehr nach einem Übertragsfehler aus.

Und hier ist auch schon der Fehler gefunden:
Codeausschnitt:

Code: Alles auswählen

  ub = 0
  While (i < sman)
    ; [...] 
    If (long < 0)
      ; Erste Zahl ist kleiner als zweite -> Übertrag
      long + #BDMaxInLong
      ub = 1
    EndIf
    help(i-eman) = long
    i + 1
  Wend
ub ist zum anfang 0, wenns dann aber mal 1 wird, bleibt es für immer 1 .
Dort fehlt also ein Else : ub = 0

@Helle: Nimm lieber mein Include :lol: , ne quatsch war n Witz :wink:
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
CSHW89
Beiträge: 489
Registriert: 14.12.2008 12:22

Re: BigDecimal - Include

Beitrag von CSHW89 »

Ja habs grad auch gefunden, wollte es nochmal testen
lg kevin
Bild Bild Bild
http://www.jasik.de - Windows Hilfe Seite
padawan hat geschrieben:Ich liebe diese von hinten über die Brust ins Auge Lösungen
Benutzeravatar
CSHW89
Beiträge: 489
Registriert: 14.12.2008 12:22

Re: BigDecimal - Include

Beitrag von CSHW89 »

Mal ne frage, kann das jemand bestätigen: ich hab grad ne komische fehlermeldung mit asm-irgendwas-blabla.

edit: liegt übrigens an 'BDExp'. hat aber vor 4.50 final noch funktioniert.
edit2: ok das liegt i-wie an den 'Protected' aufrufen in den proceduren 'BDExp' und 'BDLog'
Bild Bild Bild
http://www.jasik.de - Windows Hilfe Seite
padawan hat geschrieben:Ich liebe diese von hinten über die Brust ins Auge Lösungen
Antworten