wie erkenne ich wieviele gültige Stellen (ungleich Null) die Mantisse von Gleitkommazahlen hat

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
alfware17
Beiträge: 214
Registriert: Di 14. Dez 2010, 23:27

wie erkenne ich wieviele gültige Stellen (ungleich Null) die Mantisse von Gleitkommazahlen hat

Beitrag von alfware17 »

Ich gebe zu, mein Problem ist eigentlich kein wirkliches, denn die Funktion (formatierte Ausgabe von Zahlen) habe schon lange gelöst (siehe meinen Source unten, die alte Stdio Unit) bzw ist schon mit einfachen Pascal Mitteln zB über das writeln(x:0:3) usw möglich. Ich hatte aber mal ChatGPT gebeten, das auch zu programmieren und nach einigen Fehlerdiskusssionen sieht das Ergebnis nun eben wie folgt aus (Unit Num). Mein Problem dabei sind Rundungsfehler.

Natürlich, da wird zu viel gerechnet bzw zu oft frac() gemacht - im Vergleich zu einem str() und dann zeichenweise weiter zu arbeiten. Aber wo genau liegt nun das Problem? Zu wenige Ziffern für das geforderte Runden? Ist 84972,17 nun wirklich so verschieden von 84972,170000 wahrscheinlich ja. Aber wie kann ich erkennen, wie viele Ziffern ungleich null denn nun da sind,
entweder gesamt oder nach dem Komma. Damit könnte ich zB Runden auf 6 Stellen dann abbiegen oder auf 2 Nachkommastellen begrenzen wenn eben nur 2 da sind, Meine Beispiele mit den "Fehlern" legen mir das nahe, daß nur auf 4 Stunden gerundet werden sollte, wenn auch 4 Stellen ungleich 0 nach dem Komma da sind.

Hat jemand einen Tip für mich?
Dateianhänge
Num90.zip
(68.41 KiB) 29-mal heruntergeladen
Zuletzt geändert von alfware17 am Mi 8. Mai 2024, 09:27, insgesamt 1-mal geändert.

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2825
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: wie erkenne ich wieviele gültige Stellen ´(ungleich Null) die Mantisse von Gleitkommazahlen hat

Beitrag von m.fuchs »

alfware17 hat geschrieben: Di 7. Mai 2024, 08:15 Ich hatte aber mal ChatGPT gebeten, das auch zu programmieren
[...]
Hat jemand einen Tip für mich?
Ja: erwarte nicht von einem LLM Dinge, die es nicht kann.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

wp_xyz
Beiträge: 5203
Registriert: Fr 8. Apr 2011, 09:01

Re: wie erkenne ich wieviele gültige Stellen ´(ungleich Null) die Mantisse von Gleitkommazahlen hat

Beitrag von wp_xyz »

alfware17 hat geschrieben: Di 7. Mai 2024, 08:15 Ist 84972,17 nun wirklich so verschieden von 84972,170000
Ich denke mal - zumindest in der Physik ist es so -, dass die Genauigkeit, mit der der Wert bestimmt worden ist, den Ausschlag gibt dafür, wieviele Stellen anzugeben sind. Die geschriebenen Stellen sind gültig, alles was folgt, ist unbekannt. Insofern sind 84972,17 und 85972,170000 nicht dasselbe, denn das erstere kann in "Wirklichkeit" 84712,1743213 sein; die Messmethode ist halt im Vergleich zur zweiten so ungenau, dass sie die nachfolgenden Stellen nicht mehr erkennen kann. Nur: bei der anderen Messung würde mir auffallen, dass sie genau 4mal eine Null am Ende hat; das ist wiederum so unwahrscheinlich, dass ich eher vermuten würde, dass da jemand ohne Verständnis gearbeitet hat.
alfware17 hat geschrieben: Di 7. Mai 2024, 08:15 Aber wie kann ich erkennen, wie viele Ziffern ungleich null denn nun da sind,
Das kommt auf die Größe an, die hinter der Zahl steckt, und auf das Messverfahren. Wenn du eine Länge mit dem Meterstab misst, auf dem eine Millimeter-Skala angebracht ist, wirst du die Länge sicher nicht wesentlich genauer als 1 Millimeter messen können - der Durchmesser einer alten 30-cm Langspielplatte wäre dann 0.300 m (oder 0.301 oder 0,299 - ich weiß nicht, wie stark die schwanken...)

Unabhängig davon, falls du mit den Zahlen weiterrechnest, darfst du aber nur bei der Anzeige des Ergebnisses runden. Denn sonst hast du gleich Rundungsfehler in den Ergebnissen. Für mich ist die Funktion RoundTo normalerweise tabu...

Zweite Bemerkung: Warum bastelst du eine eigene Zahlenkonvertierungsfunktion, wenn genau dieselbe Funktion (unter anderem Namen) mehrfach in FPC sowieso vorhanden ist? FloatToStr, FormatFloat usw.?

alfware17
Beiträge: 214
Registriert: Di 14. Dez 2010, 23:27

Re: wie erkenne ich wieviele gültige Stellen ´(ungleich Null) die Mantisse von Gleitkommazahlen hat

Beitrag von alfware17 »

ja gut, mir geht es darum, dass so wie ich das sehe schon das erste Runden(84972.17 , 4) eben 84972.1699 liefert was mich ärgert. Dahar meine Frage ob ich die 2 Stellen also die .17 irgendwie erkennen könnte und dann eben gleich von vorneherein auf 2 Stellen runde und nicht auf 4. Und ja, mir ist klar oder zumindestens schwammig dass es irgendwie auch von den vielen Stellen vor dem Komma als den Gesamtstellen abhängt.

Frage 2: als ich die erste Unit (Stdio) entwickelt habe, gab es (für mich?) noch kein Lazarus und Free Pascal denn da habe ich noch mit Turbo Pascal programmiert. Und da ich auch noch 16bit machen möchte, halte ich eben die Units aktuell und am Leben für 16/32/64bit. Auch wenn es da bei Free Pascal feine Sachen gibt. Oftmals suche ich aber auch und finde nicht (zB die Sache mit den Tausender-Abtrennpunkten oder feste Vornullen).

wp_xyz
Beiträge: 5203
Registriert: Fr 8. Apr 2011, 09:01

Re: wie erkenne ich wieviele gültige Stellen ´(ungleich Null) die Mantisse von Gleitkommazahlen hat

Beitrag von wp_xyz »

alfware17 hat geschrieben: Mi 8. Mai 2024, 09:27 mir geht es darum, dass so wie ich das sehe schon das erste Runden(84972.17 , 4) eben 84972.1699 liefert was mich ärgert.
Das muss du dir abgewöhnen ;-)... Der Punkt ist, dass es die Zahl 84972.1700 in der binären Darstellung von Gleitkommazahlen einfach nicht gibt. Wie schon gesagt, nimm die Zahlen, wie sie sind, und rechne damit, und zum Schluss wandle das Ergebnis für die Anzeige in einem Label, Grid, oder was auch immer, in einen String mit der gewünschten Anzahl von Dezimalstellen um. Die FPC-Routinen machen das, so gut es geht.
alfware17 hat geschrieben: Mi 8. Mai 2024, 09:27 zB die Sache mit den Tausender-Abtrennpunkten oder feste Vornullen
Das geht für mich an Anschaulichsten mit der FormatFloat-Funktion entsprechend einer Format-Maske.
  • Jede '0' in der Maske entspricht einer Ziffer die unbedingt ausgegeben wird, notfalls als Zeichen '0'. Damit kannst du vorangestellte Nullen realisieren: FormatFloat('000000', 25) wird dargestellt als als '000025'. Falls die Zahl länger ist als die Maske werden die Ziffern trotzdem geschrieben.
  • Ein Punkt ('.') ist das Symbol für den Dezimaltrenner. Wenn du danach wieder Nullen in die Maske schreibst, dann wird die Zahl auf soviele Stellen gerundet bzw. entsprechend mit Nachkomma-Nullen aufgefüllt: FormatFloat('0.000', 25) wird zu '25.000'.
  • Das Zeichen '#' ist eine optionale Ziffer. FormatFloat('0.###', zahl) gibt mindestens eine Vorkomma-Stelle aus, hinter dem Komma maximal drei oder weniger, falls die Zahl weniger Nachkommastellen hat: FormatFloat('0.###', 1.2) wird zu '1.2', FormatFloat('0.###', 1.23456789) zu '1.234'.
  • Schließlich noch der Tausendertrenner: Wenn die Maske vor dem Dezimalpunkt ein Komma (',') enthält, wird automatisch für jede Dreiergruppe ein Tausendertrenner eingefügt. Die einfachste Art, das zu schreiben, wäre z.B. ',0' oder ',0.000' für keine oder drei Stellen nach dem Komma. Aber viele schreiben die Maske der Klarheit wegen mit #-Zeichen: '#,##0.000': das soll heißen: Tausendertrenner, mindestens eine Ziffer, drei feste Nachkommastellen (ggfs mit 0 aufgefüllt).

Antworten