Forum: PC-Programmierung C++ Rechnen mit Komma


von Unbekannt (Gast)


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

von Michael (Gast)


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.....

von GastABC (Gast)


Lesenswert?

double ist genauer.

Könnte aber auch an deinem Code liegen.
Wenn du zum Beispiel
1
float a;
2
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
1
float a;
2
a = 5.0 / 4.0;
oder

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

von Unbekannt (Gast)


Lesenswert?

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

von yalu (Gast)


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.

von Rolf Magnus (Gast)


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.

von Spess53 (Gast)


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

von Michael (Gast)


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.

von Michael (Gast)


Lesenswert?


von Rolf Magnus (Gast)


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.

von Michael (Gast)


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

von Michael (Gast)


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...

von yalu (Gast)


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++.

von Rolf Magnus (Gast)


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?

von Unbekannt (Gast)


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...

von kopfschüttel (Gast)


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

von Michael (Gast)


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....

von Rolf Magnus (Gast)


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.

von yalu (Gast)


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.

von Unbekannt (Gast)


Lesenswert?

@ yalu

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

von yalu (Gast)


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?

von yalu (Gast)


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.

von daniel (Gast)


Lesenswert?

unbekannt
http://video.google.de/videoplay?docid=6048522307950849085&q=numerical&total=1455&start=0&num=10&so=0&type=search&plindex=0

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

von daniel (Gast)


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)

von daniel (Gast)


Lesenswert?

minute  9 auch sehr interessant ;)

von Testest (Gast)


Lesenswert?

daniel wrote:
> minute  9 auch sehr interessant ;)

Diese Berechnungsformel (Rumps's Example) hätte man auch einfach durch 
sowas ersetzen können:
1
double x = 1.0e17;
2
x += 2.0;
3
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.

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
Noch kein Account? Hier anmelden.