Entwickler-Ecke

Algorithmen, Optimierung und Assembler - Genaue String ausgaben des Ergebnisses


IhopeonlyReader - Di 19.06.12 20:03
Titel: Genaue String ausgaben des Ergebnisses
(Das hier ist keine Frage, sondern eine Bitte euch alle am Thema zu beteiligen)
Guten Tag,
Ich habe mich mehrmals schon darüber geärgert, dass ich wenn ich längere Ergebnisse (mehr als 15 zifferige Zahlen) ausgeben lasse, dass das Ergebnis beispielsweise so aussieht: 2E19
Ich dachte mir nun, dass man eventuell einen Algerithmus schreiben könnte, der ein GENAUES String-Ergebnis liefert.

Folgende Ansätze:

Delphi-Quelltext
1:
2:
Function DivS(Zahl1, Zahl2: Extended; Nachkommastellen: Integer): String;
//liefert genaue Ergebnis von Zahl1/Zahl2

Theoretisch habe ich mir überlegt das Industriesystem anzuwenden und die Zahl1 jedesmal um 10 zu erhöhen und die zuletzt herausgefundene zahl mit der anzahl des Counters (10 hoch (Zahlen vor komma - vorhande herausgefundene Zahlen)) zu multipliziert und die Zahl1 mit dieser zu subtrahieren und dann von diesem Ergebnis die Nachkommastellen abschneiden und dann das Ergebnis in einen String umwandeln und das erste zeichen davon an den bisher herausgefundene Zahlenreihe anhängen...

Problem dabei: Es wird nur vor dem komma berechnet.. ein ähnlicher algerithmus müsste dann noch für nachkommastellen geschrieben werden und ein algerithmus zum herausfinden der Zahlen VOR dem Komma.

PS: Wenn man "zahlen vor dem Komma herausfinden" hört, scheint es leicht zu sein...
Aber ein Beispiel: 123456789012345678900 wäre in Delphi 1,23456789012346E20 und damit ist die einfache pos( floattostr, ',') nicht möglich...

Wer würde sich dazu bereit erklären bei einer solchen Unit zu helfen? (oder habt ihr bereits fertige? ich kenne einige die entsprechende Algerithmen verwenden... aber ich dachte an ein eigenes Gemeinschaftsprojekt)


Mathematiker - Di 19.06.12 20:19

Meinst Du so etwas:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
uses math;
procedure ausgabe;
var z:extended;
    stellen,i:integer;
    k:string;
begin
    z:=pi*sqrt(42)*1e21;                   //Beispiel
    label1.caption:=floattostr(z);   //Originalzahl
    stellen:=trunc(ln(z)/ln(10));
    z:=z/power(10,stellen);
    k:=inttostr(trunc(z));
    z:=frac(z);
    for i:=1 to stellen do begin
      z:=10*z;
      k:=k+inttostr(trunc(z));
      z:=frac(z);
    end;
    label2.caption:=k;              //Ausgabe ohne Kommata
end;

Beste Grüße
Mathematiker


IhopeonlyReader - Di 19.06.12 20:31

Das ist das was ich versucht hab in worte zu fassen ja :D
Diese ist nicht = das richtige Ergebnis... sondern nur aus den selben ziffern bestehend...

was wären denn so eure ideen?


Christian S. - Di 19.06.12 21:05

Kann man nicht einfach FloatToStrF [http://www.delphibasics.co.uk/RTL.asp?Name=FloatToStrF] benutzen? :gruebel:


IhopeonlyReader - Di 19.06.12 21:30

FloattoStrF ändert nichts am nervigen E ...

Es ist nicht das Problem die nachkommastellen abzuschneiden oder auf eine bestimme länge zu kürzen,
ich erhoffe mir, dass wir in Gemeinschaftsarbeit eine Unit erschaffen, die ein Ergebnis einer Rechnung (hautpsächlich Division) theoretisch auf ALLE nachkommastellen berechnen könnte und diese auch ausgibt !

Das heißt, es soll ein String entstehen der generell ALLE Ziffern der Zahl (ergebnis) zeigt, ohne E oder sonst irgendwelche vereinfachungen


Mathematiker - Di 19.06.12 21:31

Hallo,
also noch einmal:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
procedure ausgabe;
var z,z0,kontrolle:extended;
    nachkommastellen,gueltigestellen,stellen,i,genauigkeit:integer;
    k:string;
begin
    //Genauigkeit des verwendeten Typs extended=20 Stellen
    //bei double, ... entsprechend anpassen
    genauigkeit:=20;
    //Beispiel
    z:=pi*sqrt(42)*1e58;
    z0:=z;
    //Ausgabe Originalzahl
    label1.caption:=floattostr(z);
    //Stellenzahl-1
    stellen:=trunc(ln(z)/ln(10));
    //z auf Intervall [1,10] normieren
    z:=z/power(10,stellen);

    k:=inttostr(trunc(z));
    z:=frac(z);
    //nur maximal so viele  Vorkommastellen wie Genauigkeit
    gueltigestellen:=min(stellen,genauigkeit);
    for i:=1 to gueltigestellen do begin
      z:=10*z;
      k:=k+inttostr(trunc(z));
      z:=frac(z);
    end;
    //wenn Genauigkeit erreicht ist mit 0 auffüllen
    if gueltigestellen<stellen then
      for i:=gueltigestellen to stellen-1 do k:=k+'0';
    //nur Nachkommastellen wenn Genauigkeit noch nicht erreicht
    if stellen<genauigkeit then begin
    k:=k+',';
    for i:=1 to genauigkeit-stellen do begin
      z:=10*z;
      k:=k+inttostr(trunc(z));
      z:=frac(z);
    end;
    end;
    label2.caption:=k;
    //Kontrolle des Wertes
    kontrolle:=z0-strtofloat(k);
    label3.caption:='proz.Abweichung '+floattostr(100*kontrolle/z0)+'%';
end;

Genauer geht's kaum noch. Die prozentuale Abweichung ist für "kleine Zahlen" bis 1e18 Null, für größere im Bereich von 0,0000....... viele Nullen Prozent.
Beste Grüße
Mathematiker


Horst_H - Di 19.06.12 21:47

Hallo,

Zitat:
ich erhoffe mir, dass wir in Gemeinschaftsarbeit eine Unit erschaffen, die ein Ergebnis einer Rechnung (hautpsächlich Division) theoretisch auf ALLE nachkommastellen berechnen könnte und diese auch ausgibt !


Trifft das auf: Periodenberechnung von Dezimalbrüchen [http://www.entwickler-ecke.de/topic_Periodenberechnung+von+Dezimalbruechen_108866.html] nicht schon zu?

Gruß Horst


Christian S. - Di 19.06.12 21:47

@IhopeonlyReader: Du willst also eine eigene Divisionsfunktion schreiben, die als Ergebnistyp kein Extended, sondern einen (sehr langen) String hat?



(Ich hoffe, Du weißt, wie "das nervige E" wirklich heißt und was es bedeutet ...)


Mathematiker - Di 19.06.12 21:50

Hallo,
meine letzte Antwort und Deine haben sich irgendwie überschnitten.
user profile iconIhopeonlyReader hat folgendes geschrieben Zum zitierten Posting springen:
die ein Ergebnis einer Rechnung (hautpsächlich Division) theoretisch auf ALLE nachkommastellen berechnen könnte und diese auch ausgibt !
Das heißt, es soll ein String entstehen der generell ALLE Ziffern der Zahl (ergebnis) zeigt, ohne E oder sonst irgendwelche vereinfachungen

Das verstehe ich nun nicht mehr. Alle Ziffern eines Bruchs bedeutet, die Vorperiode und die Periode selbst. Meinst Du das?
Dazu sich hat Horst_H gerade geäußert.
Alle Ziffern eines reellen Ergebnisses, z.B. Wurzel 2 ..., ist Quatsch, da der Rechner nur mit rationalen Werten rechnet und irrationale Zahlen unendlich viele Nachkommastellen haben. ALLE Ziffern geht dann nicht.
Beste Grüße
Mathematiker