Seite 1 von 1

Problem mit Fließkommazahlen in Zählern

Verfasst: Montag 7. Juli 2003, 17:44
von Kartoffel
Immer diese Fließkommazahlen, dauernd habe ich Probleme mit denen :?

Also hier ist mein Problem, ich hoffe jemand kann mir helfen:

Ich will, dass eine Zählervariable bei jedem Durchlauf um eine beliebige Zahl erhöht wird, die auch eine Fließkommazahl sein kann.
Nun haben Fließkommazahlen ja keine absolute genauigkeit. Bei einer einzelnen Zahl macht das zwar keinen großen Unterschied, aber wenn ich die Zählerschleife ein paar mal durchlaufen lasse, summiert sich dieser Fehler ja.
Hat jemand einen Vorschlag, wie ich diesen Effekt zumindest minimieren kann.

Ich habe mir selbst schon Gedanken gemacht. Mein Ansatz war, den Zähler nach jedem hochzählen auf so viele Stellen zu runden, wie die Variable hat, um die hochgezählt werden soll.
Dadurch währe immer nur ein Fehler vorhanden, da die anderen weggerundet würden. Kann das so funktionieren und wenn ja, wie finde ich heraus, wie viele Stellen eine Fließkommazahl hat?

Verfasst: Montag 7. Juli 2003, 17:47
von hans
Hallo Kartoffel, was ist der Grund, daß du unbedingt Fließkommazahlen verwenden mußt?

Wenn du das Ergebnis bei jedem Durchlauf rundest, ist der Fehler nach 1000 Durchläufen nicht gerade klein. Ich würde dieses nicht so machen. Gib doch mal ein kurzes Beispiel.

Hans

Verfasst: Montag 7. Juli 2003, 18:03
von Dookie
Hi Kartoffel,

ich würd auch gerne wissen, warum Floats? Wenn Du z.B. mit Währungen rechnenn willst, nimm doch cent oder 1/10 cent und dividiere dann durch 100 bzw 1000 um den Eurobetrag zu bekommen. Oder bastel Dir Deine eigene Klasse.


Gruß

Dookie

Verfasst: Montag 7. Juli 2003, 18:06
von Kartoffel
Ich schreibe ein Programm, das Graphen von Mathematischen Funktionen ausdrucken soll.
Dazu will ich Funktionswerte berechnen, deren Abstand kleiner als eins ist.

Verfasst: Montag 7. Juli 2003, 18:13
von Dookie
also wenn Du ein Intervall von 0-1 in 0.01er Schritten willst, nimm eben ein

Code: Alles auswählen

for i in range(101):
    x = i/100.0
    y = funktion(x)
    plot(x,y)
Gruß

Dookie

Verfasst: Montag 7. Juli 2003, 18:18
von Kartoffel
0.01, 0.02, 0.03 <-Da kommt schon der erse Fehler, denn das ist 0.029999999999999999

Und wie gesagt, das summiert sich, denn ich will ja einen größeren Bereich berechnen.

Verfasst: Montag 7. Juli 2003, 18:20
von hans
so ganz komme ich nicht weiter. über welchen Wertebereich reden wird denn? 10E-3, 10E-6, ..... ist alles kleiner 1.

Sorry hab deine letzte Mail nicht richtig gelesen. Lass den Wert so stehen! Genauer gehts mit EDV nicht. Vielleicht wüde da ein 64 Bit System etwas weiterhelfen. Das Problem wird aber nie vollständig gelöst. Die Ausgabe solltest du allerdings auf x Nachkommastellen formatieren.

Hans

Verfasst: Montag 7. Juli 2003, 18:25
von Kartoffel
Also, der Wertebereich sieht folgendermaßen aus:
Der Benutzer gibt den Bereich des Koordinatensystems an, der gezeichnet werden soll. (zB von x=-5 bis x=10)
Dann werden in einem bestimmten Abstand (zB 0.01) Werte für die Funktion ausgerechnet.

Also in meinem Beispiel für -5; -4,99; ...;10
Mein Problem ist, dass die Fehler in der Genauigkeit bestimmter Fließkommazahlen dazu führen, dass zum Beispiel der letzte x-Wert nicht genau 10 ist

Verfasst: Montag 7. Juli 2003, 18:33
von hans
Das Thema hatten wir schon einmal. Hier der Thread: http://python.sandtner.net/viewtopic.ph ... sc&start=0

also wieviele Nachkommastellen angezeigt werden ist glaube ich nicht so interessant zu wissen. Sorge bitte dafür, dass deine Zahlen mit hinreichender Gnauigkeit dargestellt werden. Ein Wert von 4,999 oder 5,001 ist meistens mit 5,00 hinreichend genau beschrieben. Kommt immer auf den Einzelfall an.

Wenn du immer diese Genauigkeit vorraussetzt, dann wirs du nie einen Autoatlas aufschlagen dürfen, weil dir alle Karten viel zu ungenau sind. Selbst mit Satellietenaufnahmen hast du auf Grund von Verzerrungen dein Genauigkeitsproblem. Dies mal nur so als Beispiel.

Hans

Verfasst: Montag 7. Juli 2003, 18:46
von Dookie
Hi also

Code: Alles auswählen

>>> for i in range(50,101):
...     print i/100.0
... 
0.5
0.51
0.52
0.53
0.54
0.55
0.56
0.57
0.58
0.59
0.6
0.61
0.62
0.63
0.64
0.65
0.66
0.67
0.68
0.69
0.7
0.71
0.72
0.73
0.74
0.75
0.76
0.77
0.78
0.79
0.8
0.81
0.82
0.83
0.84
0.85
0.86
0.87
0.88
0.89
0.9
0.91
0.92
0.93
0.94
0.95
0.96
0.97
0.98
0.99
1.0
>>> 
was willst Du mehr?

Gruß

Dookie

Verfasst: Montag 7. Juli 2003, 18:48
von Dookie
von -0.5 an gehts auch

Code: Alles auswählen

>>> for i in range(-50,101):
...     print i/100.0,
... 
-0.5 -0.49 -0.48 -0.47 -0.46 -0.45 -0.44 -0.43 -0.42 -0.41 -0.4 -0.39 -0.38 -0.37 -0.36 -0.35 -0.34 -0.33 -0.32 -0.31 -0.3 -0.29 -0.28 -0.27 -0.26 -0.25 -0.24 -0.23 -0.22 -0.21 -0.2 -0.19 -0.18 -0.17 -0.16 -0.15 -0.14 -0.13 -0.12 -0.11 -0.1 -0.09 -0.08 -0.07 -0.06 -0.05 -0.04 -0.03 -0.02 -0.01 0.0 0.01 0.02 0.03 0.04 0.05 0.06 0.07 0.08 0.09 0.1 0.11 0.12 0.13 0.14 0.15 0.16 0.17 0.18 0.19 0.2 0.21 0.22 0.23 0.24 0.25 0.26 0.27 0.28 0.29 0.3 0.31 0.32 0.33 0.34 0.35 0.36 0.37 0.38 0.39 0.4 0.41 0.42 0.43 0.44 0.45 0.46 0.47 0.48 0.49 0.5 0.51 0.52 0.53 0.54 0.55 0.56 0.57 0.58 0.59 0.6 0.61 0.62 0.63 0.64 0.65 0.66 0.67 0.68 0.69 0.7 0.71 0.72 0.73 0.74 0.75 0.76 0.77 0.78 0.79 0.8 0.81 0.82 0.83 0.84 0.85 0.86 0.87 0.88 0.89 0.9 0.91 0.92 0.93 0.94 0.95 0.96 0.97 0.98 0.99 1.0
>>>

Verfasst: Montag 7. Juli 2003, 19:47
von hans

Code: Alles auswählen

#!/usr/bin/python
i = -0.05
s = 0.01
while i < 0.050001:
  print "%5.2f   %.25f" % (i,i)
  i = i + s
ergibt

Code: Alles auswählen

[hans@rosi tmp]$ ./teste.py
-0.05   -0.0500000000000000027755576
-0.04   -0.0400000000000000008326673
-0.03   -0.0299999999999999988897770
-0.02   -0.0199999999999999969468867
-0.01   -0.0099999999999999967387199
 0.00   0.0000000000000000034694470
 0.01   0.0100000000000000036776138
 0.02   0.0200000000000000038857806
 0.03   0.0300000000000000058286709
 0.04   0.0400000000000000077715612
 0.05   0.0500000000000000097144515
[hans@rosi tmp]$
Rechne an Hand des Beispieles doch einmal aus, wieviel Verlust du machst, wenn du eine Millionen Stück zu 0,03 Euro verkaufst und die ......58286709 großzügig abrundest.

Glaub mir, in dem Fall lohnt es nicht. Dafür bekommste nicht einmal einen Löffel billige Marmelade, geschweige den ein Bier oder Getränk nach Wahl.

Ich habe noch gelernt mit Rechnschieber und fünf- und siebenstelliger Logaithmentafel umzugehen. Und da waren die Abweichungen wesentlich größer und trotzdem ist die Welt nicht an den zu großen Toleranzen zu Grunde gegangen.

Verfasst: Dienstag 8. Juli 2003, 14:24
von Kartoffel
Danke, Dookie. So was ähnliches hatte ich mir über Nacht auch schon überlegt.

Ansonsten glaub ich sogar, dass die Abweichung zu vernachlässigen ist, ich bin eben Perfektionist und will supergenaue Zahlen ohne langen Rattenschwanz von Nullen dran haben.

Ich würde sagen, ich erkläre mein Problem hiermit offiziell für erledigt. Vieleicht mach ichs so ähnlich wie der Vorschlag von Dookie, oder ich finde mich mit den "unschönen" Zahlen endgültig ab. Trotzem nochmal danke an alle!

Edit:
Hier ist meine Funktion:

Code: Alles auswählen

def floatrange (start, stop, step): return map(lambda x: x*step, range(start/step, stop/step+1))