Ich hab schon viel gesucht und es liegt wohl an Ungenauigkeiten von float, aber ich konnte nichts finden wie ich das Problem in den Griff bekomme. Eigentlich müsste doch ein Float vom Wertebereich und der Genauigkeit da locker reichen? Es gibt auch ein Application Note von Atmel zu Funktionen zu Divisionen, aber da gehts nur um ganzzahlige Werte. Da muss es doch eine Standardlösung geben für sowas, das Problem hat man doch bestimmt immer wieder. Es geht nicht nur um diesen einen Wert, sondern darum dass die Ergebnisse immer stimmen. Diesen Wert hab ich nur zufällig gefunden.
>1/0.002 = 499 also 1/0.002 = 499.0 ? oder 1/0.002 = 499.999976251 ? Wenn danach ein Integer daraus werden soll: 1/0.002 + 0.5 = 500 Stichwort: Runden Ein einfacher cast auf Integer schneidet nur die Nachkommastellen ab. >Float vom Wertebereich ... und ... Genauigkeit da locker reichen? Float hat einen sehr grossen Wertebereich (wegen des Exponenten), aber nur eine Genauigkeit von 23 Bit (Mantisse), das ist weniger als long (32Bit). Das Verhälthis 500/499.999976251 gibt genau die maximal erreichbare Genauigkeit in Dezimaldarstellung an: ca. 7 signifikante Stellen (ergibt sich aus 2^23 = 8388608). Siehe auch http://de.wikipedia.org/wiki/IEEE_754 Wenn du genauer rechnen willst, brauchst du ein anderes Zahlenformat.
Hallo, nein, die Genaugkeit reicht nicht für eine exakte Rechnung, da Zehntel nicht exakt als Binärbruch dargestellt werden können. Wenn Du das Ergebnis auf 7 oder schlimmstenfalls 6 Dezimalstellen rundest, sieht es wieder gut aus. Schöne Grüße, Peter
Hmmm... Gibt es dazu ein Warning? ich hätte jetzt mal ganz grob vermutet (meine c vorlesungen sind schon etwas länger her), dass du 1.0/0.002 machen muss. sonst nimmt er 1 als integer. Probier es mal aus, bin mir wie gesagt nicht mehr so sicher :-)
Lothar Miller wrote: >>1/0.002 = 499 > also 1/0.002 = 499.0 ? > oder 1/0.002 = 499.999976251 ? Ja, genau da liegt das Problem, hab ich übersehen dass beim casten zu Int der Rest einfach abgeschnitten wird. > Wenn danach ein Integer daraus werden soll: > 1/0.002 + 0.5 = 500 Ich bin nicht so sicher ob ich richtig liege, aber wenn ichs recht verstehe passt das Konstukt mit "+0,5" für jede möglich Division, oder? Und wenn ich das weiter denke: Im Prinzip würde es reichen nicht 0,5 sondern nur so viel zu addieren wie beim float mit der jeweiligen Genauigkeit maximal als Fehler auftreten kann, oder? Aber wenn 0,5 universell passt dann mach ich das natürlich immer so und meine Anwendung ist gerettet, vielen Dank! 1.0/0.002 brachte übrigens keine Lösung des Problems, es ist schon die Sache mit dem Runden.
Stephan S. wrote: > Ich bin nicht so sicher ob ich richtig liege, aber wenn ichs recht > verstehe passt das Konstukt mit "+0,5" für jede möglich Division, oder? Ja, zumindest fast. Bei negativen Zahlen musst du -0,5 rechnen:
1 | unsigned long Round(double Value) |
2 | {
|
3 | if (Value < 0) |
4 | return (unsigned long) (Value - 0.5) |
5 | else
|
6 | return (unsigned long) (Value + 0.5) |
7 | }
|
> 1.0/0.002 brachte übrigens keine Lösung des Problems, es ist schon die > Sache mit dem Runden. Nein, zwischen
1 | 1/0.002 |
und
1 | 1.0/0.002 |
gibt es aus C-Sicht keinen Unterschied. In beiden Fällen wird die Division als double ausgeführt.
ebenfalls besteht die möglichkeit aus der stdlib "math.h" sich der funktionen ceil() bzw. floor() zu bedienen.
Gehts oder kannst du nicht vielleicht (1*x/(0,002*x)) = 500 rechnen? mit x = 1000 wärst du im reinen int-Bereich.
bohner wrote: > ebenfalls besteht die möglichkeit aus der stdlib "math.h" sich der > funktionen ceil() bzw. floor() zu bedienen. Das setzt doch aber soweit ich das grad verstehe voraus dass ich weiß ob der Rundungsfehler die Zahl kleiner oder größer macht als ich erwarte. Kann man das generell im Voraus wissen? Gibts nicht einfach eine Funktion die auf ganze Zahlen rundet wie man es gewohnt ist ohne einfach was abzuschneiden?
Wolfgang Birner wrote: > Gehts oder kannst du nicht vielleicht (1*x/(0,002*x)) = 500 rechnen? mit > x = 1000 wärst du im reinen int-Bereich. Das hab ich mir gestern auch schon gedacht und getestet, funktionierte aber nicht. Grad eben kam mir aber dann doch die Erleuchtung: selbst wenn ich 0,002 * 1000 rechne ists 2.0, also noch immer vom Typ float. Wenn man das dann nach einem int Typen castet läufts! Bleibt nur noch die Frage ob es bei der Berechnung vom Produkt auch zu Fehlern kommt die dann wieder als Ergebnis z.B. 1.99999995 haben und dann das casten wieder schief läuft.
Beim normalen int oder so: var * 10; var + 5; var / 10; fertig. MW
Stephan S. wrote: > Gibts nicht einfach eine Funktion die auf ganze Zahlen rundet wie man es > gewohnt ist ohne einfach was abzuschneiden? Klar gibts die. Sie steht drei Posts über dem von mir jetzt zitierten. Beitrag "Re: 1/0.002 = 499 Wie krieg ich da 500 raus?"
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.