Problem mit Float
lima-city → Forum → Programmiersprachen → C/C++ und D
beitrag
betracht
cast
doubeln
entfernt inhalt
ergebnis
falsches ergebnis
fehler
gedacht
genau abgespeichert
gleichheit
main
maschine
paar anmerkungen
rms
rundungsfehler
thw
verla
versuch
zehnerpotenz
-
Ich habe eine Anwendung in C++ geschrieben, die eine Zahl z.B. 12.78
in 1278 verwandeln soll. Mein Quelltext dazu sieht wie folgt aus:
#include<iostream>
using namespace std;
int main ()
{
float f;
int i;
f = 83.96;
i=static_cast<int>(f * 100);
cout<<i;
cin>>i;
}
Dabei erhalte ich 8395. Da ich absoluter C++ Anfänger bin weiss ich nicht weiter und bitte daher um Hilfe.
Beitrag geändert: 13.10.2007 16:24:16 von rms -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
#include<iostream>
using namespace std;
int main ()
{
float f;
int i;
f = 83.96f;
i = static_cast<int> (f * 100);
i++;
cout << i;
cin.get();
cin.get();
return 0;
}
Ich meine der Zählt die Null auch als Zahl. Weiß aber nicht so genau. außerdem musst du Deinen Code echt verbessern das ist schrecklich ^^
Geb den Variablen immer bessere Bedeutungen als f oder i, gewöhn es dir jetzt schon ab nur i oder f zu schreiben, weil später bringt Dich das sehr durcheinander! -
Ich habe keine Ahnung, warum dieses Problem auftritt, aber dass er bei der Null mit dem Zählen anfängt ist falsch.
Folgender Code führt ja zum falschen Ergebnis 83.95 (ich hab mal die Literale richtig geschrieben, also ein f bei den Floats angehängt):
#include<iostream> using namespace std; int main () { float f; int i; f = 83.96f; i = static_cast<int>(f*100.0f); cout<<i; cin>>i; }
dieser Code führt dagegen zum richtigen Ergebnis 83.96
#include<iostream> using namespace std; int main () { float f; int i; f = 83.96f; f = f*100.0f; i = static_cast<int>(f); cout<<i; cin>>i; }
Im Nachhinein einfach 1 dazuzuaddieren funktioniert so nicht, da kommt sonst für Zahlen wie f = 83.94f ein falsches Ergebnis raus.
-
Anstatt wild mit casts rumzuschießen, reicht hier auch schon ein einfaches
i = (int) f;
Auch wenn das eigentlich C ist, bevor jmd. meckert.
Beitrag geändert: 15.10.2007 21:31:06 von bitwax -
bitwax schrieb:
Und was du machst ist kein cast??
Anstatt wild mit casts rumzuschießen,
reicht hier auch schon ein einfaches
Schön, aber was hilft uns das????
i = (int) f;
Es tritt immer noch der selbe Fehler auf.
-
natürlich ist das ein cast.
war auch nur zum vorbeugen gedacht.
Beitrag geändert: 15.10.2007 22:47:33 von bitwax -
zum runden von float's nach integer kann man immer 0.5 addieren,
bevor von double nach integer konvertiert wird.
#include<iostream> using namespace std; int main () { float f; int i; cout<<"f:"; cin>>f; i=(int)(f*100.0+0.5); cout<<"i:"<<i; return 0; }
Beitrag geändert: 15.10.2007 23:02:28 von tiwag -
@tiwag: Es geht hier nicht ums mathematische Runden sondern ums korrekte Abrunden. Außerdem gib bei deinem Programm mal 0.005 ein =>
Also dieser Fehler ist wirklich gerade was die Zahlendarstellung im Computer angeht, kenne ich mich eigentlich ganz gut aus (würde ich mal behaupten).
Noch ein paar Anmerkungen:
1. Z. B. für f = 83.96001f ist das Ergebnis noch 8396.
2. Der »Fehler« (Ergebnis 8395) tritt auf meiner Windows/P4-Maschine (mit MinGW kompiliert) auf, auch auf meiner PIII-Linuxbox (mit g++ kompiliert) auf ABER er tritt bei meiner Unix/PowerPC (g++) Maschine nicht auf, da ist das Ergebnis 8396.
Also ein Hinweis, dass es was konkret mit dem Prozessor zu tun hat (wenn jemand mal den Code in Pascal o. ä. übersetzt, kompiliert und das Ergebnis mitteilt wäre das sehr nett).
Bei Java gibt mir so was wie
public class Main{ public static void main(String [] args){ float f; int i; f = 83.96f; i = (int) (f*100.0f); System.out.println(i); } }
übrigens 8396 aus. Auf die virtuelle Maschine ist halt Verlass
Beitrag geändert: 15.10.2007 23:43:49 von cga -
Ich bedanke mich bei den Versuchen mir zu helfen bei mir tritt das Problem auch unter Linux auf
EDIT thw: Doppelpost entfernt, Inhalt des zweiten Postings war:
Mit der "gültigen" Adresse meine ich, dass wenn man zb. google.at eingiebt kommt ja dann auch http://www.google.at/ und das soll der dann auch aktualisieren
mfG
Beitrag geändert: 29.10.2007 19:58:34 von thw -
Also 'ne schnelle und elegante Lösung hab ich jetzt nicht parat, aber ich kann zumindest nachvollziehen woher der Rundungsfehler kommt. Du musst im Hinterkopf haben dass Fließkommawerte (float und double) im Gegensatz zu z.B. long nie genau abgespeichert werden, sondern immer nur näherungsweise. Eine Ganzzahl kann (im jeweiligen Wertebereich) genau dargestellt werden, eine reelle Zahl wird intern immer als x^y (hoch) abgespeichert, was natürlich oft nicht genau die gewünschte Zahl ist. Diese Rundungsfehler resultieren dann ganz einfach aus den abgespeicherten Näherungswerten. Das ist auch der Grund weshalb man sich bei Fließkommaberechnungen nie zu sehr auf's Ergebnis verlassen sollte und weshalb man float und double nicht auf Gleichheit prüfen kann.
Wenn du bei dieser Tahl auf Biegen und Brechen den Dezimalpunkt loswerden willst, besteht noch die Möglichkeit, das ganze als String zu betrachten und den Punkt einfach zu entfernen. Ist halt aufwändig und langsam und nicht besonders elegant... aber dafür in jedem Fall genau ;)
MfG,
thw -
Die schnellste un eleganteste Lösung wären in dem Fall warhrscheinlich zehnerpotenzen. o.O
13,37 * 10² = 1337
1337 * 10^-2=13,37
Einfach mal googlen oder wikin. -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage