Seite 2 von 4
Verfasst: 27.01.2006 12:18
von Zaphod
ich verstehe nicht wo das problem liegt. wenn du round sagst das es aufrunden soll, dann rundet es auf.
60.00000000004 ist eben größer als 60.0 und wird, wenn du round sagst es soll aufrunden aufgerundet.
round ist dafür gut, wofür es gedacht ist. zum thema gleitkomma ungenauigkeit muß man eigentlich auch nichts mehr sagen. ich empfehle das studium dieser beiden links:
was ist approximation:
http://de.wikipedia.org/wiki/Approximation
ist die gleitkomma darstellung eventuel approximativ?:
http://de.wikipedia.org/wiki/Flie%C3%9Fkomma-Zahlen
Verfasst: 27.01.2006 12:19
von Gimbly
Klar kann der arme round-Befehl 60.000004 nur zu 61 aufrunden, aber er darf nicht 100 * 0.6 zu 61 aufrunden.
Der Bug besteht natürlich dadrin, dass 100 * 0.6 falsch gerechnet wird.
Das kenne ich aus C und Delphi anders.
Verfasst: 27.01.2006 12:23
von Ypser
Vielleicht sollte Fred, wie in anderen Programmiersprachen auch, für solche Dinge die Befehle
Floor() und Ceil() einführen, und dafür Round() endlich zu einem intelligenten Befehl machen.
Stümperversion:
Code: Alles auswählen
Procedure Round_Intelligent(v.f)
nc.f = (v - Int(v))
If (nc >= 0.5)
pr.l = Int(v + 1)
Else
pr.l = Int(v)
EndIf
Procedurereturn pr
EndProcedure
Verfasst: 27.01.2006 12:32
von Zaphod
c und delphi haben das selbe problem. das ist nämlich keine eigenschaft der programmiersprache sondern der floating point unit. in c und delphi hat man allerdings doubles, bei denen die approximation natürlich besser funktioniert.
Verfasst: 27.01.2006 12:34
von Batze
Gimbly hat geschrieben:
Der Bug besteht natürlich dadrin, dass 100 * 0.6 falsch gerechnet wird.
Um genau zu sein gibt es den Wert 0.6 im Binären Floats garnicht.
Das ist doch im Dezimalsystem genauso.
30 * 0.333333333 ist doch auch nicht genau 10.
0.6 ist im Binärsystem ebenfalls eine Ungenaue Zahl.
Aber ließ dir die Links durch.

Verfasst: 27.01.2006 13:02
von Froggerprogger
Der Bug besteht natürlich dadrin, dass 100 * 0.6 falsch gerechnet wird.
Das kenne ich aus C und Delphi anders.
Hier ein äquivalenter C-Code und ein Java-Code:
Code: Alles auswählen
#include <stdio.h>
#include <math.h>
int main(void) {
float f;
int i;
f = 100.0f * 0.6f;
printf("%f\n",f);
printf("%f", ceil(f));
}
Code: Alles auswählen
public class RoundTest {
public static void main (String [] args) {
float f = 100.0f * 0.6f;
System.out.println(f);
System.out.println(Math.ceil(f));
}
}
Beide liefern als Ergebnis:
60.000004
61.000000
Lässt man das 'f' hinter dem Zahlenliteral weg, wird es als ein double-Literal interpretiert, daher dann in C auch mit doubles gerechnet und anschließend implizit nach float gecastet, wodurch das Ergebnis scheinbar richtig wird, da die Ungenauigkeit dann außerhalb der von floats liegt. Bei Java wird beim weglassen der 'f' eine cast-exception geworfen, da man explizit von double auf float downcasten muss, um diesen Effekt nur bewußt einzusetzen.
In Delphi wird es dasselbe sein. Das ist kein PB-Bug, sondern eine Ungenauigkeit bei floats.
Verfasst: 27.01.2006 13:05
von MARTIN
Ja, eben.
Eine float Variable kann einfach nicht genau den Wert 0.6 annehmen, sodern nur einen Wert um 0.6.
In C gibt es dieses Problem genau so:
Zeigt :60.000003814697
So jetzt wurde es 10mal gesagt.
/*Edit :Eigentlich habe ich mein Beitrag schon gegen 12.15 gepostet vor dem Beitrag von Batze*/
Verfasst: 27.01.2006 13:05
von Batze
Es ist zwecklos das jedes mal wieder zu erklären.
Am besten irgendwer erklärrt das mal in einem Thread der dann in Anfänger als besonders wichtig markiert ist.
Verfasst: 27.01.2006 13:25
von Froggerprogger
Man könnte auch die RTFM-Keule schwingen:
Aus der Hilfe zu "Variablen, Typen und Operatoren"
Spezielle Informationen über Fließkommazahlen (Floats)
Eine Fließkomma-Zahl (auch Gleitkomma-Zahl, englisch: Floating Point Number) wird in einer Art und Weise gespeichert, die den Binär-Punkt (trennt "Ganzzahlteil" vom "Kommateil") innerhalb der Zahl "gleiten" lässt, wodurch das Speichern sehr großer aber auch sehr kleiner Zahlen (mit vielen Nachkommastellen) möglich wird. Wie auch immer, Sie können nicht sehr große Zahlen mit gleichzeitig sehr hoher Genauigkeit (sozusagen große und kleine Zahlen zur selben Zeit) speichern. Eine weitere Einschränkung von Fließkomma-Zahlen ist, dass sie stets im Binärmodus arbeiten, weshalb sie nur die Zahlen exakt speichern können, welche mittels Multiplikation oder Division mit 2 ermittelt werden können. Dies ist insbesondere wichtig zu wissen, wenn Sie versuchen, eine Fließkommazahl in einer visuell lesbaren Form darzustellen (oder mit ihr Rechenoperationen auszuführen) - das Speichern von Zahlen wie 0.5 oder 0.125 ist einfach, da sie Divisionen von 2 sind. Das Speichern von Zahlen wie 0.1 ist schwieriger, diese wird möglicherweise als Zahl 0.9996125 gespeichert. Sie können versuchen, nur eine begrenzte Anzahl an (Nachkomma-) Stellen darzustellen, seien Sie aber nicht überrascht, wenn die Darstellung der Zahl anders aussieht, als Sie dies erwarten!
Dies gilt für alle Fließkomma-Zahlen, nicht nur die in PureBasic.
Verfasst: 27.01.2006 15:23
von Falko
Wenn jemand Lust hat, dieses in PB umzusezten, dann kehrt Ruhe ein
http://vb-tec.de/runden.htm