mikrocontroller.net

Forum: PC-Programmierung C++ Rechnen mit Komma


Autor: Unbekannt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Ih möchte mit Komma rechnen...
Datentyp: float

Mein Problem ist, dass ich im Komma-Berech nie einen exakten wert 
bekomme.

Gibt es vielleicht einen Datentyp, der genau ist?

MFG Unbekannt

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ih möchte mit Komma rechnen...
> Datentyp: float

>Mein Problem ist, dass ich im Komma-Berech nie einen exakten wert
>bekomme.

Was genau möchtest du denn rechnen?????

>Gibt es vielleicht einen Datentyp, der genau ist?

Mit bcd kannst du mit beliebiger Genauigkeit rechnen, aber es würde mich 
doch sehr wundern, wenn das nötig sein sollte.....

Autor: GastABC (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
double ist genauer.

Könnte aber auch an deinem Code liegen.
Wenn du zum Beispiel
float a;
a = 5 / 4;
schreibst, rechnet der Computer erstmal mit Integer-Werten.
5/4 wäre dann 1 + 1 Rest.
a wäre also = 1.

beser wäre
float a;
a = 5.0 / 4.0;
oder

float a;
a = (double)5 / (double)4;

Autor: Unbekannt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich möchte einen Taschenrechner programmieren...
dazu benötige ich auch das Komma!

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Auf einem PC ist float etwa 7, double etwa 15 und long double etwa 20
Stellen genau. Wenn du viele Rechenschritte hintereinander ausführst,
pflanzt sich der Fehler jeweils fort und wächst deswegen in jedem
Schritt. Dieses Problem hat ein normaler Taschenrechner aber
ebenfalls.

Es gibt Bibliotheken, die Rechenoperationen mit (fast) beliebiger
Genaugkeit zur Verfügung stellen, bspw. die MPFR-Bibliothek. Das geht
dann auf Kosten der Rechengeschwindigkeit und des Speichers. Auch das
in dieser Bibliothek verwendete Zahlenformat kann die meisten Zahlen,
bspw. 1/3=0,33333... oder sqrt(2)=1,41421... zwar sehr genau, aber
nicht absolut exakt darstellen.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ih möchte mit Komma rechnen...
> Datentyp: float

Besser double, wie andere schon geschrieben haben.

> Mein Problem ist, dass ich im Komma-Berech nie einen exakten wert
> bekomme.

Das ist die Natur von Fließkommazahlen.

> Gibt es vielleicht einen Datentyp, der genau ist?

Da Computer nur begrenzten Speicher haben, kann man prinzipbedingt nicht 
jeden beliebigen reelen Zahlenwert exakt speichern.

Autor: Spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>ch möchte einen Taschenrechner programmieren...
>dazu benötige ich auch das Komma!

Wo? Bei der Eingabe, beim Rechnen oder bei der Ausgabe.

MfG Spess

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
... wie ganz oben schon geschrieben: Schau dir mal BCD-Zahlen und 
Rechenoperationen an. Im Prinzip rechnet dann den uC wie ein Mensch auf 
Papier. Die Genauigkeit kann unendlich hoch gesetzt werden (eine 
sinnvolle Beschränkung sei aber empfohlen) Der Algorihmus ist in 10 
Minuten geschrieben.

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Die Genauigkeit kann unendlich hoch gesetzt werden

Auch in BCD wirst du Schwierigkeiten haben, z.B die Wurzel von 2 exakt 
(also mit "unendlicher" Genauigkeit) darzustellen.

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
:-) Ich sehe da keine Schwierigkeit.

Hier ein Link, wie man "händisch" Wurzel zieht. Mit BCD-Zahlen kann man 
das wunderbar in ein uC Programmieren.

http://www.diaware.de/html/wurzel.html

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich frage mich nur, warum hier jeder auf float und double rumreitet. 
Sind alle so Hochsprachengeschädigt??

Wenn einer etwa glauben sollte, dass er gut C programmieren kann ohne 
ASM zu beherrschen, so kann ich darüber höchstens schmunzeln...

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> :-) Ich sehe da keine Schwierigkeit.

:-) Ich schon.

> Hier ein Link, wie man "händisch" Wurzel zieht. Mit BCD-Zahlen kann
> man das wunderbar in ein uC Programmieren.

So dass sqrt(2) exakt, d.h. unendlich genau berechnet wird?
Beliebig genau hätte ich gerade noch akzeptiert, aber auch nur dann,
wenn man die Möglichkeit, hat, den Rechner mit beliebig viel
Speicher auszustatten.

> Ich frage mich nur, warum hier jeder auf float und double rumreitet.
> Sind alle so Hochsprachengeschädigt??

Das Thema des Threads ist nun mal C++.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ich frage mich nur, warum hier jeder auf float und double rumreitet.
> Sind alle so Hochsprachengeschädigt??
> Wenn einer etwa glauben sollte, dass er gut C programmieren kann ohne
> ASM zu beherrschen, so kann ich darüber höchstens schmunzeln...

Der Ursprungsposter möchte ein kleines Taschenrechner-Programm für den 
PC schreiben. Findest du wirklich, daß er dazu erst eine auf BCD-Zahlen 
basierende Mathe-Bibliothek in Assembler schreiben sollte?

Autor: Unbekannt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Danke für eure antworten!

Ich glaube ich habe mein Problem noch
zu ungenau beschrieben:

Wenn ich mit float rechne habe ich das Problem, dass zB.:
1/5 sollte 0,2 ergeben. Mein Ergebniss: 0,200000002980232
Ich weiss jedoch nicht woher diese letzten stellen kommen...

Autor: kopfschüttel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wenn du zum Beispiel
>
> float a;
> a = 5 / 4;
>
> schreibst, rechnet der Computer erstmal mit Integer-Werten.
> 5/4 wäre dann 1 + 1 Rest.
> a wäre also = 1.

Was ist das für ein Müll? Ist das bei allen verbreiteten Hochsprachen 
so? Wenn a als float definiert ist, sollte 5/4 doch 1.25 ergeben

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Yalu, ohne dir zu Nahe treten zu wollen:

Lies bitte doch mal dein Posting noch einmal durch, schalte dein Hirn 
ein und komm auf den Boden....

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> Wenn du zum Beispiel
>>
>> float a;
>> a = 5 / 4;
>>
>> schreibst, rechnet der Computer erstmal mit Integer-Werten.
>> a wäre also = 1.
>
> Was ist das für ein Müll?

Was meinst du damit?

> Ist das bei allen verbreiteten Hochsprachen so?

Dürfte weit verbreitet sein.

> Wenn a als float definiert ist, sollte 5/4 doch 1.25 ergeben

Die Definition von a hat nichts, aber auch gar nichts mit dem Ergebnis 
von "5/4" zu tun. 5 ist ein int, 4 ebenso, also wird eine 
Integer-Division durchgeführt. Wohin das Ergebnis danach dann irgendwann 
mal geschrieben wird, ist dabei nicht relevant.

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wenn ich mit float rechne habe ich das Problem, dass zB.: 1/5 sollte
> 0,2 ergeben. Mein Ergebniss: 0,200000002980232 Ich weiss jedoch
> nicht woher diese letzten stellen kommen...

Das liegt daran, dass der PC-Prozessor (wie die meisten anderen
Prozessoren auch) im Dualsystem rechnet. 0,2 im Dezmalsystem ist

  0,0011001100110011...

im Dualsystem, hat also unendlich viele Nachkommastellen, ähnlich wie

  1/11 = 0,0909090909...

im Dezimalsystem.

Da für die Speicherung der Zahlenwerte nur begrenzt viel Speicherplatz
zur Verfügung steht, können nicht alle Nachkommastellen berücksichtigt
werden, so dass ein kleiner Fehler ensteht.

Rundest du das Ergebnis von 1/5 bei der Ausgabe auf die in meinem
ersten Post angegebenen 7 Stellen, sieht man den Fehler nicht mehr.

Die durch das intern verwendete Zahlenformat enstehenden Abweichungen
sind vor allem bei kaufmännischen Anwendungen ein Schönheitsfehler,
weil Geldbeträge mit zwei Nachkommastellen im Dezimalsystem exakt, im
Dualsystem i.Allg. aber nur ungenau darstellbar sind. Deswegen rechnen
die meisten Taschenrechner in dem von Michael vorgeschlagenen
BCD-System (binary coded digits).

Bei technisch-wissenschaftlichen Anwendungen ist das jedoch
Augenwischerei, da sowohl der mittlere als auch der maximale Fehler in
der Dualdarstellung deutlich kleiner als bei einer gleichviele
Speicherbits umfassenden BCD-Darstellung ist. Da zudem reine
Dualarithmetik auf den meisten Prozessoren deutlich schneller läuft
als BCD-Arithmetik, wird letztere nur für Spezialanwendungen

eingesetzt.

Autor: Unbekannt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ yalu

Das heisst wenn ich ein ,,schöneres" Ergebnis, das jedoch ungenauer ist
sollte ich mit BCD-Systhem rechnen...

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Michael:

Du schriebst:
> Yalu, ohne dir zu Nahe treten zu wollen:
>
> Lies bitte doch mal dein Posting noch einmal durch, schalte dein
> Hirn ein und komm auf den Boden....

Vielleicht ist das etwas unklar rübergekommen:

Rolf Magnus schrieb:
> Auch in BCD wirst du Schwierigkeiten haben, z.B die Wurzel von 2
> exakt (also mit "unendlicher" Genauigkeit) darzustellen.

womit er völlig recht hat, weil sqrt(2) sowohl in Dual- als auch in
Dezimaldarstellung unendlich viele Stellen hat und somit auf einem
Rechner mit endlicher Speicherkapazität nicht darstellbar ist.

Daraufhin entgegnetest du:
> :-) Ich sehe da keine Schwierigkeit.

Den Smiley habe ich übrigens nicht übersehen, deswegen habe ich - für
den Fall, dass deine Antwort nicht ganz ernst gemeint war - vor meine
Antwort einen ebensolchen gestellt.

Dass es Algorithmen gibt, mit der man - genügend Zeit und Speicher
vorausgesetzt - eine Wurzel auf beliebig viele Stellen ausrechnen
kann, ist schon klar. Aber unendlich viele Stellen gehen nur mit
unendlich viel Speicher, also überhaupt nicht.

Oder hat dich etwas anderes an meinem Beitrag gestört?

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Das heisst wenn ich ein ,,schöneres" Ergebnis, das jedoch ungenauer
> ist sollte ich mit BCD-Systhem rechnen...

Ich würde das Ergebnis für die Bildschirmanzeige einfach auf eine
vernünftige Stellenzahl runden, dann sieht das Ergebnis auch bei der
normalen C++-Arithmetik 'schön' aus.

Autor: daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
unbekannt
http://video.google.de/videoplay?docid=60485223079...

ich glaub du kommst sehr naiv an die sache ran
die frage die man stellen sollte, geht das überhaupt genau?
ja, benutze rational
nein, entscheide oder lass den user entscheiden wie genau er es haben 
will.
danach richten sie die algorithmen

wozu brauchst du den taschenrechner?
eine übung für dich selbst?
wenn ja, dann konzentiere dich lieber auf die software architektur

wenn keine übung benutze fertige excellente tools wie
octave, python, R, ruby und viele andere
oder schaue richtung symbolisches rechnen
das ist die richtung in der ich die wenigstge erfahrung habe

grüsse

Autor: daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
.. in fact people can argue and i can argue that prior to digital 
computing
astronomer and engineres that did computing with paper and pencil
knew more about the accuracy of what they were computing than we do now 
..

zitat aus dem video (minute 7)

Autor: daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
minute  9 auch sehr interessant ;)

Autor: Testest (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
daniel wrote:
> minute  9 auch sehr interessant ;)

Diese Berechnungsformel (Rumps's Example) hätte man auch einfach durch 
sowas ersetzen können:
double x = 1.0e17;
x += 2.0;
printf("x = %f\n", x);
bei dem ich auch einen absoluten Fehler von 2 habe.

Das erwähnte Ariane 5 Beispiel hat auch nichts mit dem Problem der 
Fließkommaarithmetik zu tun. Wenn ich eine neue Maschine baue und nicht 
den Wertebereich der Sensoren überprüfe, kann ich nicht das Zahlensystem 
dafür verantwortlich machen (und daran würde auch 'Interval Arithmetic' 
nichts ändern).

Man kann float nutzen, man muss nur wissen wo die Grenzen sind und wann 
ich es benutzen kann.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.