Forum: Compiler & IDEs Warum ist 3.219 kleiner 3.2?


von AVRli (Gast)


Lesenswert?

Hallo,

ich grübel hier gerade warum der folgende Vergleich wahr ist.

if (3.219 < 3.2) {
  mach was...
}

Hmm was macht der µC da? ;-)

Gruß AVRli...

von sven (Gast)


Lesenswert?

Hab es ausprobiert! Bei mir macht er nix!

(Atmega 128)

Reading specs from C:/Programme/WinAVR/lib/gcc/avr/3.4.6/specs
Configured with: ../gcc-3.4.6/configure --prefix=/c/WinAVR --target=avr 
--enable
-languages=c,c++ --with-dwarf2 --enable-win32-registry=WinAVR 
--disable-nls
Thread model: single
gcc version 3.4.6


Ein paar mehr Infos bei deinem Thread wären schon sinnvoll.

von jubatus (Gast)


Lesenswert?

Interessanter ist, was der Compiler daraus macht.
-> Siehe Assembler-Code

von gast (Gast)


Lesenswert?

ich würde sowas nicht so machen. Besser ist es die Differenz zu rechnen 
und dann auch > oder < 0 prüfen.

von Spocki (Gast)


Lesenswert?

warum soll das besser sein?

von Thomas P. (tpircher) Benutzerseite


Lesenswert?

gast wrote:
> ich würde sowas nicht so machen. Besser ist es die Differenz zu rechnen
> und dann auch > oder < 0 prüfen.

Kannst du das genauer ausfuehren? Das wuerde mich jetzt wirklich 
interessieren.

Thomas

von Sven P. (Gast)


Lesenswert?

Thomas Pircher wrote:
> gast wrote:
>> ich würde sowas nicht so machen. Besser ist es die Differenz zu rechnen
>> und dann auch > oder < 0 prüfen.
>
> Kannst du das genauer ausfuehren? Das wuerde mich jetzt wirklich
> interessieren.
>
> Thomas

Also nochmal die Gebetsmühle.
Sven P. wrote:
> Ganz ehrlich? OK:
> Fließkommazahlen sind schlicht und einfach wie eine Seuche. Jeder Depp
> (nicht persönlich nehmen, bitte) will sie haben, aber keiner ist bereit,
> sich mal mit ihren Grundlagen zu beschäftigen.
> Und ja, selbst moderne computergesteuerte Sternwarten kommen heute
> problemlos ohne Fließkomma aus.
>
> Also: Skaliere den Kram herauf, berechne deine Sachen möglichst klug
> (überlege dir, in welcher Reihenfolge die Teilrechnungen am besten
> erledigt werden, sodass sich möglichst viel rauskürzt und du keine
> Überläufe riskierst). Danach das Komma richtig setzen und bingo.
> Stichwort: Scaled Integer. Warum mit 0,004 Metern rechnen, wenns mit 4
> Millimetern genauso geht?
>
> Den Fließkommadreck kann man benutzen, wenn man nicht von vorneherein
> weiß, welche Dimensionen die Werte annehmen, da sie einerseits einen
> großen Bereich, andrerseits diesen aber lückenhaft und ungenau abdecken.

Fließkommazahlen sind ungenau, deshalb soll man die nicht direkt 
vergleichen.

von AVRli (Gast)


Lesenswert?

Ich bin über mich selber gestolpert. :-(

if (3.219 < 3.2) {
  mach was...
}

richtig ist das ich eigendlich das mache...

...
#define c_triger 3.3
...

if (3.219 < c_triger) {
  mach was...
}

so und da dann 3.3 der Wert ist muß das Ergebniss logisch wahr sein... 
brettvormkopf... :-( Ich bin davon ausgegangen das ganz oben in der 
Einleitung 3.2 angegeben war... naja sorry für den Beitrag!

Gruß AVRli...

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Sven P. wrote:
> Fließkommazahlen sind ungenau

Würde ich so nicht sagen. Sie funktionieren anders als Integer, und wenn 
man sie wie Integer behandelt wird man auf die Nase fallen, aber sie 
sind nicht per se ungenau.

> deshalb soll man die nicht direkt vergleichen.

Das gilt nur für Gleichheit (==), nicht für größer/kleiner.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Andreas Schwarz wrote:

>> deshalb soll man die nicht direkt vergleichen.
>
> Das gilt nur für Gleichheit (==), nicht für größer/kleiner.

Selbst für Gleichheit gibt es Dinge, die garantiert funktionieren,
bspw. ein Vergleich auf eine exakte 0.  Eine solche entsteht u. a.
durch die (default-)Initialisierung der statischen und globalen
Variablen.  Es ist also durchaus sinnvoll und zulässig, eine globale
Variable pro Programmlauf ein einziges Mal setzen zu wollen
(natürlich auf einen Wert verschieden von 0 :), indem man schreibt:
1
   if (global_var == 0.0) {
2
      global_var = something_that_results_in_not_0();
3
   }

von Thomas P. (tpircher) Benutzerseite


Lesenswert?

Sven P. wrote:
> Also nochmal die Gebetsmühle.
>> Fließkommazahlen sind schlicht und einfach wie eine Seuche.
>> [...]
>> Stichwort: Scaled Integer.

Damit bin ich einverstanden: ich kann mich nicht erinnern wenn ich das 
letzte mal floats verwendet habe. Ich verstehe dass man 
Fliesskommazahlen nicht mit == vergleichen soll, aber die Anleitung 
eines Posters, "a < b" durch ein "a - b < 0" zu ersetzen, scheint mir 
grober Unfug zu sein.

> Fließkommazahlen sind ungenau, deshalb soll man die nicht direkt
> vergleichen.

Damit bin ich nicht einverstanden, jedenfalls wenn die Vergleiche < oder 
> sind und man in Kauf nimmt, dass das auch <= und >= bedeuten kann.

Aber das (mittlerweile geloeste) Problem des OP, dass 3.219 < 3.2 
anscheinend wahr ist, sollte doch nicht auftreten, auch nicht mit den 
ungenauesten Fliesskommazahlen.

Thomas

von Sven P. (Gast)


Lesenswert?

Thomas Pircher wrote:
> Ich verstehe dass man
> Fliesskommazahlen nicht mit == vergleichen soll, aber die Anleitung
> eines Posters, "a < b" durch ein "a - b < 0" zu ersetzen, scheint mir
> grober Unfug zu sein.
Isses auch, ich bezog mich auf '==', wobei mir gerade auffällt, dass das 
doch unklar war, tschuldigung. :-)

>> Fließkommazahlen sind ungenau, deshalb soll man die nicht direkt
>> vergleichen.
>
> Damit bin ich nicht einverstanden, jedenfalls wenn die Vergleiche < oder
>> sind und man in Kauf nimmt, dass das auch <= und >= bedeuten kann.
Jo, läuft ja aufs Gleiche hinaus. Ich beziehe mich auf Vergleiche nach 
'=='. Relationen sind schon ok.
Gleiches für Andreas, ich beziehe mich auf Vergleiche mit '=='.

> Aber das (mittlerweile geloeste) Problem des OP, dass 3.219 < 3.2
> anscheinend wahr ist, sollte doch nicht auftreten, auch nicht mit den
> ungenauesten Fliesskommazahlen.
Nö, den Fehler hat er/sie ja auch gefunden.

Ein Vergleich mit '== 0.0' KANN bei kaputten FPUs auch in die Hose 
gehen, Null kann auch negativ sein. Sowas solls schonmal gegeben haben 
grins, allerdings nicht, wenn man, wie du vorschlägst, eine konstante 
Initialisierung vornimmt, klar.

Fließkomma sind insofern ungenau, als dass sie keinen Anspruch darauf 
erheben, jeden Wert darstellen zu können. Der Zahlenraum ist nämlich 
nicht fließend (ja, so ist das auch nicht gemeint, aber viele meinen 
das) sondern hat Lücken und Löcher.
Man kann zwar ausrechnen, wo genau die sind, aber dann kann man auch 
gleich Festkomma benutzen...

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Man kann "==" auch für Floats verwenden, wenn man weiß was man tut. Lua 
z.B. verwendet ausschließlich Float-Variablen auch für Ganzzahlen 
(http://lua-users.org/wiki/FloatingPoint).

von Sven P. (Gast)


Lesenswert?

Andreas Schwarz wrote:
> Man kann "==" auch für Floats verwenden, wenn man weiß was man tut. Lua
> z.B. verwendet ausschließlich Float-Variablen auch für Ganzzahlen
> (http://lua-users.org/wiki/FloatingPoint).

Lua passt dann aber auch auf, dass es exakt bleibt, und rundet 
entsprechend :-)

von Karl H. (kbuchegg)


Lesenswert?

Andreas Schwarz wrote:
> Man kann "==" auch für Floats verwenden, wenn man weiß was man tut.

Ich denke, genau das ist der springende Punkt:
Wenn man weiß, was man tut, ist das alles kein Problem.
Aber wenn man naiv in Floating Point herangeht (auch normale double sind 
da keine Ausnahme, die Probleme werden nur von der Größenordnung her 
kleiner), dann kann man sich da eine Menge Probleme einhandeln an denen 
man schier verzweifeln kann.

Ich empfehle jedem, das hier mal durchzuarbeiten:
http://www.physics.ohio-state.edu/~dws/grouplinks/floating_point_math.pdf

Auch, wenn man vieles daraus so nicht wieder braucht, so schärft es doch 
das Verständniss dessen, wo die Probleme liegen.

von Sven P. (Gast)


Lesenswert?

Karl-Heinz: Das unterschreibe ich so bedingungslos :-)

Auch weiterhin füg ich hinzu: In fast allen Fällen sind Fließkommazahlen 
überflüssig.

von möp (Gast)


Lesenswert?

Aus diesem Grund sind bei Firmen Fließkommazahlen (meist) strikt 
verboten.

von Karl (Gast)


Lesenswert?

Klar, deswegen wird auch nirgends Matlab eingesetzt (rechnet 
standardmäßig mit double) ;), deshalb gibt es auch keine Controller mit 
FPU... wozu hat man die eigentlich?

Also ehrlich: The right tool for the right job. Für schnelle Regler auf 
einem AVR ist float natürich nichts. Aber wenn ich alle Sekunde mal ne 
Wurzel brauche, tu ich mir den Krampf nicht an und implementier das als 
Fixedpoint nochmal neu. Das Problem sitzt wie üblich eher vor dem 
Computer.

von Sven P. (Gast)


Lesenswert?

Karl wrote:
> Klar, deswegen wird auch nirgends Matlab eingesetzt (rechnet
> standardmäßig mit double) ;), deshalb gibt es auch keine Controller mit
> FPU... wozu hat man die eigentlich?

Weiß nicht, jedenfalls braucht man Fließkommazahlen schonmal nicht, um 
Sternwarten zu betreiben... grins

> Also ehrlich: The right tool for the right job. Für schnelle Regler auf
> einem AVR ist float natürich nichts. Aber wenn ich alle Sekunde mal ne
> Wurzel brauche, tu ich mir den Krampf nicht an und implementier das als
> Fixedpoint nochmal neu. Das Problem sitzt wie üblich eher vor dem
> Computer.
Es geht doch garnicht um Geschwindigkeit :-|

von Karl (Gast)


Lesenswert?

Doch, es geht um Geschwindigkeit! Und zwar darum, wie schnell man zum 
Ziel kommt (Zeit == Geld).

von Sven P. (Gast)


Lesenswert?

Oh Klasse. Trifft natürlich voll die Kernproblematik, wenn man 
Fließkommazahlen nicht verstanden hat und einfach drauf los rechnet.

von Karl (Gast)


Lesenswert?

Es trifft die Problematik der Verteufelung von floats, bloß weil man sie 
nicht verstanden hat. Siehe dein "Argument":
>Weiß nicht, jedenfalls braucht man Fließkommazahlen schonmal nicht, um
>Sternwarten zu betreiben...

Man braucht floats auch nicht, um Apfelkuchen zu backen.

von Sven P. (Gast)


Lesenswert?

Un-be-lehr-bar. Entweder willst du mich nicht verstehen, oder du hast 
das mit den Fließkommazahlen wirklich nicht verstanden. Keine der beiden 
Varianten möchte ich dir aber pauschal unterstellen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Sven P. wrote:
> Un-be-lehr-bar. Entweder willst du mich nicht verstehen, oder du hast
> das mit den Fließkommazahlen wirklich nicht verstanden. Keine der beiden
> Varianten möchte ich dir aber pauschal unterstellen.

Du bist aber auch ziemlich unbelehrbar.  Oder besser gesagt, du
bestehst partout darauf, dass nichts außer deiner Reinen Lehre
gelten darf.  Fließkommazahlen sind ein bequemes Mittel, um Zahlen
mit einem großen Dynamikbereich in für viele Fälle brauchbarer
Genauigkeit darstellen zu können, und sie sind noch dazu Bestandteil
des C-Standard-Sprachumfangs, was die Bequemlichkeit ihrer Nutzung
einfach mal drastisch erhöht.  Sie haben ihre Grenzen, keine Frage,
aber auch 16-bit-Integers haben ihre Grenzen, trotzdem werden sie
häufig genug (auch und gerade im Controller-Bereich) benutzt.

Deine gebetsmühlenartige Wiederholung, dass sie gar nicht nötig
wären, erinnert an die ebenso gebetsmühlenartige Konstatierung einiger
Programmierer, dass alles außer Assemblerprogrammierung gar nicht
nötig wäre.  Im Prinzip richtig, aber wie Karl schon schrieb: Zeit
ist Geld, und wenn ich mein Problem mit Standard-Bordmitteln des
C-Compilers hinreichend genau gelöst bekomme, fange ich nicht an,
umständlich in Assembler zu programmieren oder eben umständlich
mit irgendeiner Fixpoint-Arithmetik zu jonglieren.  Das mache ich
genau dann, wenn ich es brauche: Assembler, wenn es sich in C nicht
mehr sinnvoll ausdrücken lässt, Fixpoint, wenn mir Wertebereich und/
oder Genauigkeit von Fließkommazahlen nicht genügen.  Die Benutzung
von Nicht-Standard-Mitteln birgt in jedem Falle eine höhere Fehler-
wahrscheinlichkeit, weil einem der Compiler weniger Arbeit abnehmen
kann.  Damit wird nicht nur die Entwicklungszeit länger, sondern auch
der Wartungsaufwand höher.

Dass man neben den Möglichkeiten die Grenzen seiner Werkzeuge kennen
muss, steht natürlich außer Zweifel.  Das gilt aber genauso für die
Genauigkeit (oder eben nicht exakte Vergleichbarkeit) von Gleitkomma-
zahlen zu wie für die Tatsache, dass 65535 + 1 = 0 (statt 65536) ist,
wenn man mit einer vorzeichenlosen 16-bit-Ganzzahl arbeitet.  Wenn man
diese Grenzen nicht beachtet, erlebt man einfach mal sein blaues Wunder.

von Sven P. (Gast)


Lesenswert?

Jörg:
Ich stimme dir in jedem Teil deiner Ausführung zu.

Vielleicht hab ich dashier:
> Doch, es geht um Geschwindigkeit! Und zwar darum, wie schnell man zum
> Ziel kommt (Zeit == Geld).
auch einfach falsch interpretiert. Aber Fließkommazahlen sind ganz und 
garkein Werkzeug, das man mal eben schnell einsetzt. Es bedarf halt 
Zeit, um sie zu verstehen und dann im konkreten Anwendungsfall 
abzuschätzen, ob und inwieweit sie brauchbar sind.

Ich krieg halt immer nervösen Ausschlag, wenn jemand so etwa meint, 'mit 
Float wär das einfacher'.
Ich habe meinen Teil an Floats verstanden und benutze sie auch häufig, 
aber ich habe mich vorher auch Tagelang mit Standards nach IEEE und so 
weiter auseinandergesetzt (und hab bis heute noch nicht jedes Detail 
verstanden, sodass ich oft nachgucken muss, inwieweit irgendeine 
Operation 'legal' ist).

Daher die Aufregung und Gebetsmühle. Wenn Karl seine Floats 
verinnerlicht hat, ist das auch ok, da will und wollte ich ihm nichts 
unterstellen. Tschuldigung, wenn das doch so rübergekommen ist.

von Simon K. (simon) Benutzerseite


Lesenswert?

Ich kann Sven schon ein wenig verstehen. In der Schule, sogar im Studium 
haben wir bisher nie behandelt wann man Floats verwenden darf und kann. 
Bei Integern hingegen schon (Maximaler Zahlenraum 2^n-1 und sowas).
Es wird einfach weggelassen. Man sagt Float und Double sind für 
Gleitkommazahlen und fertig.

Bei meinem Cousin befand sich sogar eine Frage in einer 
Informatikklausur, wo nach einem optimalen Datentyp für Währungen 
gefragt war und da gab es dann auch nur Integer oder Float. Und Float 
war natürlich richtig, weil es ja eine Gleitkommazahl war... Autsch.

von Karl (Gast)


Lesenswert?

Das ist allerdings echt heftig, da schlicht falsch. Gerade bei 
Finanzsoftware wird mit 100stel Cent "Integern", also fixedpoint, 
gerechnet.

Wir haben im Studium schon kurz behandelt, wie ein float aufgebaut ist, 
aber so richtig verstanden hat das damals wohl keiner (behaupte ich 
mal). Ich bin auch nicht für "nimm float und das passt dann schon", 
sondern für den Einsatz von Gleitkommazahlen (NICHT Fließpunkt oder 
dergleichen...), wo sie sinnvoll sind. Und das kommt bei den ewigen 
"float ist pöse"-Wiederholungen einfach nicht zur Geltung. Spätestens 
wenn etwas nicht so funktioniert wie man sich es vorgestellt hat, sollte 
man halt mal recherchieren...

Viele Grüße
Karl, der mit floats bei 3D-Grafikberechnungen auch schon auf die 
Schnauze gefallen ist ;)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Karl wrote:
> Das ist allerdings echt heftig, da schlicht falsch. Gerade bei
> Finanzsoftware wird mit 100stel Cent "Integern", also fixedpoint,
> gerechnet.

Kommt natürlich auch drauf an.  Solange du in einer Währungseinheit
bleibst, ist ein um 100 (oder 1000) skalierter Integer sicher die
beste Wahl.  Wenn man aber zwischen verschiedenen Währungseinheiten
mit variablen Umrechnungsfaktoren arbeiten muss, sieht die Sache
schon wieder ganz anders aus...

von Falk W. (dl3daz) Benutzerseite


Lesenswert?

Jörg Wunsch wrote:
...
> Fließkommazahlen sind ein bequemes Mittel, um Zahlen
> mit einem großen Dynamikbereich

Dynamikbereich ist ja fast das Gegenteil von Auflösung/Genauigkeit.

> in für viele Fälle brauchbarer
> Genauigkeit darstellen zu können, und sie sind noch dazu Bestandteil
> des C-Standard-Sprachumfangs,

Das sind viel, auch umstrittene Dinge.

> was die Bequemlichkeit ihrer Nutzung
> einfach mal drastisch erhöht.  Sie haben ihre Grenzen, keine Frage,

Die sind aber sehr komplex.

> aber auch 16-bit-Integers haben ihre Grenzen, trotzdem werden sie
> häufig genug (auch und gerade im Controller-Bereich) benutzt.

Integers haben einen großen Vorteil: Die Auflösung ist immer exakt 1. 
Der Dynamikbereich ergibt sich aus der Anzahl Bits.

> Deine gebetsmühlenartige Wiederholung, dass sie gar nicht nötig
> wären,

In der realen Welt halte ich Floats auch für unnötig. Am Ende ist der 
Input immer ein Integer. Auch die 1,234 µV gibt der ADC als Integer aus.

Am Ausgang sind auch wieder Integer. Eine PWM ist immer nur A/B, mit A 
und B als Integer, was Du in den DAC steckst, ist ein Integer...

> erinnert an die ebenso gebetsmühlenartige Konstatierung einiger
> Programmierer, dass alles außer Assemblerprogrammierung gar nicht
> nötig wäre.  Im Prinzip richtig, aber wie Karl schon schrieb: Zeit
> ist Geld, und wenn ich mein Problem mit Standard-Bordmitteln des
> C-Compilers hinreichend genau gelöst bekomme, fange ich nicht an,
> umständlich in Assembler zu programmieren oder eben umständlich
> mit irgendeiner Fixpoint-Arithmetik zu jonglieren.

Sobald Du schwer verständliche Effekte mit Floats hast, ist der 
Zeitvorteil aber schnell aufgefressen.

> Das mache ich
> genau dann, wenn ich es brauche: Assembler, wenn es sich in C nicht
> mehr sinnvoll ausdrücken lässt, Fixpoint, wenn mir Wertebereich und/
> oder Genauigkeit von Fließkommazahlen nicht genügen.  Die Benutzung
> von Nicht-Standard-Mitteln birgt in jedem Falle eine höhere Fehler-
> wahrscheinlichkeit, weil einem der Compiler weniger Arbeit abnehmen
> kann.  Damit wird nicht nur die Entwicklungszeit länger, sondern auch
> der Wartungsaufwand höher.

Je komplexer das eingesetzte Werkzeug ist, umso größer sind die 
Probleme, wenn das Werkzeug etwas anderes tut, als erwartet.

> Dass man neben den Möglichkeiten die Grenzen seiner Werkzeuge kennen
> muss, steht natürlich außer Zweifel.  Das gilt aber genauso für die
> Genauigkeit (oder eben nicht exakte Vergleichbarkeit) von Gleitkomma-
> zahlen zu wie für die Tatsache, dass 65535 + 1 = 0 (statt 65536) ist,
> wenn man mit einer vorzeichenlosen 16-bit-Ganzzahl arbeitet.  Wenn man
> diese Grenzen nicht beachtet, erlebt man einfach mal sein blaues Wunder.

Und ich behaupte, daß die Grenzen eines Integers leicht zu definieren 
sind, die eines Floats eben nicht.

Und deswegen kann ich mir keine sinnvolle Anwendung von Float 
vorstellen, die letzten Endes nicht sinnvoller mit Integers gelöst 
werden kann.

Aber ich freue mich über Gegenbeispiele.

73,
Falk

von (prx) A. K. (prx)


Lesenswert?

Man kann vieles mit Integern machen, was in ganz natürlicher Form erst 
einmal auf Fliesskommarechnung raus liefe. Nur wird das dann manchmal 
deutlich umständlicher.

So kann man Mondphasenanzeige, Sonnenaufgang und dergleichen sicherlich 
sogar mit BCD- oder ASCII-Arithmetik rechnen. Nur erschliesst sich mir 
nicht, warum man vorhandene Trigonometriefunktionen mit Gewalt umgehen 
sollte, bloss weil manche Vergleiche bei Fliesskommadarstellung 
problematisch sind - die man dafür garnicht benötigt.

Dass man wissen sollte was man tut ist unstrittig. Gilt aber ziemlich 
universell, denn mit Integer-Rechnung kann man aufgrund wesentlich 
wahrscheinlicheren Überlaufs genauso Schiffbruch erleiden. Eine 
Problematik die hier im Forum alle naselang aufkreuzt.

Wohlgemerkt: Ich will hier nicht der Fliesskommarechnung für einfache 
Temperaturumrechung und ADC-Skalierung das Wort reden. Ist da meist 
überflüssig. Bloss hat dieser Thread für mich irgendwie schon was 
Komisches:

Da hat jemand ein Problem und hat erkennbar Fliesskommarechnung 
verwendet, wobei weder Code noch Aufgabenstellung bekannt sind. Prompt 
stürzen sich manche Leute geradezu reflexhaft auf die 
Fliesskommarechnung, obwohl grösser/kleiner Relationen eher 
unproblematisch sind. Weshalb das natürlich auch nicht aufhört als sich 
herausstellt, dass es sich um einen simplen Tippfehler und ein stark 
irreführendes Posting handelte. Aber auf Prinzipien reitet es sich halt 
am besten.

von Gruenschnabel (Gast)


Lesenswert?

A.K. hat ja schon das Wesenliche geschrieben.
Ich denke, daß viele µC-Programmierer von float wie printf abgeschreckt 
werden, weil selbst bei nur einmaliger Verwendung die Codegröße 
explosionsartig ansteigt. Auf kleineren AVRs laufen diese Programme dann 
einfach nicht.
Aber auch Integer hat seine Tücken. Wer 10/3*1000 rechnet, wird auch 
schimpfen.
In der Faschingszeit hat es mir immer Spaß gemacht, beim hiesigen Bäcker 
nach 17 Uhr Pflaumenpfannkuchen zu kaufen - zum halben Preis. Einer hat 
57 Cent gekostet. Zwei Stück folgerichtig 58 Cent :-)
Zuerst hatte ich protestiert, aber dann hat mich dieser eine Cent immer 
zum Schmunzeln gebracht.

von Falk W. (dl3daz) Benutzerseite


Lesenswert?

A. K. wrote:

...

> Da hat jemand ein Problem und hat erkennbar Fliesskommarechnung
> verwendet, wobei weder Code noch Aufgabenstellung bekannt sind. Prompt
> stürzen sich manche Leute geradezu reflexhaft auf die
> Fliesskommarechnung, obwohl grösser/kleiner Relationen eher
> unproblematisch sind. Weshalb das natürlich auch nicht aufhört als sich
> herausstellt, dass es sich um einen simplen Tippfehler und ein stark
> irreführendes Posting handelte. Aber auf Prinzipien reitet es sich halt
> am besten.

Zur Aufheiterung die graphische Darstellung eines typischen 
Integer-Problems: http://xkcd.com/571/

Falk

von Karl H. (kbuchegg)


Lesenswert?

> Aber auf Prinzipien reitet es sich halt am besten.

Da hast du schon recht.
Das Problem bei Floating Point ist, dass es kein "One size fits all" 
gibt. Man muss jeden Fall im Grunde neu betrachten und sich überlegen, 
was alles passieren kann. Oft (meistens) kommt man auch ohne eine 
derartige Analyse durch ohne dass irgendetwas Gröberes passiert. Aber 
dann gibt es auch noch die "harten Fälle", die einem den Schweiß auf die 
Stirn treiben können. Vor allem dann, wenn die Float Operationen sich 
über mehrere Berechnungen hinziehen.

Ich hab mal ein Beispiel gefunden. Es stammt aus "Geometric and Solid 
Modeling, Christoph Hoffmann" und zeigt, wie man je nachdem wie man 
rechnet (wobei beide Arten mathematisch völlig gleichwertig sind) zu 
völlig unterschiedlichen Ergebnissen kommen kann. Selbst wenn man ein 
Epsilon berücksichtigt!

<quote>
Consider implementing a test of whether two points in the plane are 
equal. Specifically assume that the point u is the intersection of the 
pair of lines (L1,L2), and that the point v is the intersection of the 
lines (L3,L4). The line equations are the input to the following 
algorithm:

1. Compute the coordinates of u.
2. By substituting into the line equations L3 and L4, conclude that
u == v if both L3(u) and L4(u) are smaller then some tolerance.

Intuitively, this algorithm ought to be equivalent to a second version 
in which the roles of u and v are reversed. Lets see if this is true.

(Hint: a1 denotes 'a' with a subcscript of 1)

1. The intersectoin (ux, uy) of the lines
1
   a1*x + b1*y + c1 = 0 
2
   a2*x + b2*y + c2 = 0
is computed as:
1
   D = a1*b2 - a2*b1 
2
   ux = (b1*c2 - b2*c1) / D 
3
   uy = (a2*c1 - a1*c2) / D
2. The point (ux,uy) is assumed to lie on the line
1
   a*x + b*y + c = 0
   if the distance is small; that is if
1
   |a * ux + b * uy + c| < eps * sqrt(a*a + b*b)

We assume eps to be 1E-10, a reasonable bound for double precision. We 
ask whether u and v are incident using 2 different methods:

a. Compute the coordinates of u
   conclude that u == v, iff u is on both L3 and L4.
b. Compute the coordinates of v
   conclude that u == v, iff v is on both L1 and L2.

The line coefficients follow. Since pow(2,-23) ~ 1E-7, they differ from 
1 and 0 by amounts that are several orders of magnitude larger then eps.
1
  L1: a1 = -1; b1 = 1; c1 = 0 
2
  L2: a2 = -(1+pow(2,-23)); b2 = 1-pow(2,-23); c2 = pow(2,-22) 
3
  L3: a3 = 1; b3 = 0; c3 = -(1+pow(2,-15)) 
4
  L4: a4 = 0; b4 = 1; c4 = -(1+pow(2,-15))

These coefficients can be represented exactly in double precision. The 
coordinates of the points are now computed to be
1
u = ( 1.0, 1.0 ) 
2
v = ( 1.000030517578125, 1.000030517578125)

They are both exact. Moreover since ai*ai + bi*bi is aproximately 
between
1 and 2, the evaluation of the line equations after substituting the 
point coordinates yields an error that can be compared directly with 
eps. We obtain the values
1
L3(u) ~ -3E-5        > eps 
2
L4(u) ~ -3E-5        > eps
from which we conclude that u connot be incident to v, since it is too 
far from the lines L3, L4 whose intersection is v.

But we also obtain
1
L1(v) = 0            < eps 
2
L2(v) ~ -7E-12       < eps
from which we must conclude that v is incident to u, since it lies 
extremely close to both lines.
Therefore, although they ask the same geometric question, the two 
computations yield contradictory results.

So what can one do about this.
Clearly: Don't use that algorithm. One could choose to do:

1. Compute the coordinates of u and v, by intersecting the respective 
lines.
2. If the euclidian distance between u and v is smaller then eps,
     decide u == v;
   otherwise
     decide u != v

(Note that this computation is more 'expensive' then the previous one. 
This time both points and an euclidian distance needs to be computed. In 
the previous algorithm only one point is computed and the testing does 
not involve a square root.)

This method is symetric, but it does not exhibit transitivity. 
Specifically, we choose 3 points u, v and w such that u is incident to 
v, v is incident to w, but u is not incident to w. We assume an eps of 
1E-10
1
u = ( 0, 0 ) v = ( 0, 0.8E-10) w = ( 0, 1.6E-10 )
Clearly the distance between the adjacent pairs is less then eps, but 
the distance between u and w is greater then eps. So what is the correct 
answer? Are all those points equal or are they not?
</quote>

von P. S. (Gast)


Lesenswert?

Jörg Wunsch wrote:

> Kommt natürlich auch drauf an.  Solange du in einer Währungseinheit
> bleibst, ist ein um 100 (oder 1000) skalierter Integer sicher die
> beste Wahl.  Wenn man aber zwischen verschiedenen Währungseinheiten
> mit variablen Umrechnungsfaktoren arbeiten muss, sieht die Sache
> schon wieder ganz anders aus...

Auch dann hast du exakt zu rechnen und darfst keine Cent unter den Tisch 
fallen lassen. Leider verstehen das selbst in der Bank-IT einige Leute 
nicht...

von Sven P. (Gast)


Lesenswert?

Wobei mich aber auch niemand daran hindert, mit Integern zu rechnen und 
für den trigonometrischen Kram halt die entsprechenden Float-Funktionen 
zu benutzen. Geschwindigkeitsmäßig isses Pott wie Deckel. Wenn ich aber 
danach runde und wieder mit Ganzzahlen weiterrechne, bin ich wenigstens 
wieder in einem einfachen und leicht berechenbaren Zahlenraum.
Dass ich mir auf die Weise zwangsläufig Gedanken darum machen muss, was 
denn mit etwaigen Nachkommastellen passiert, ist dabei noch positiver 
Nebeneffekt.

von Markus K. (markus-)


Lesenswert?

Nach den ganzen Argumenten für Integer will ich auch noch mal ein 
Argument für Floats bringen:
Auf manchen Architekturen ist float-Arithmetik schneller als 
Integer-Artithmetik, z.B. bei der M32R-Familie von Renesas.

von Gruenschnabel (Gast)


Lesenswert?

>Auf manchen Architekturen ist float-Arithmetik schneller als
>Integer-Artithmetik, z.B. bei der M32R-Familie von Renesas.

Interessant. Kannst Du Zeiten nennen z.B. für 1.0+1.0 und 1+1?

von (prx) A. K. (prx)


Lesenswert?

Wir sich wohl eher auf Multiplikation und Division beziehen. Da werden 
diese Integer-Operation auch schon mal auf dem Umweg über die 
Fliesskommaeinheit durchgeführt, weshalb das dann mehr Zeit braucht als 
die Fliesskomma-Operationen.

Das war beispielsweise auch bei Intels Prozessoren schon der Fall. 
Pentium: IMUL 10-11 Takte, FMUL 3 Takte. Wenn man FMUL und die 
Konvertierungen zusammenrechnet kommt man ungefähr bei IMUL raus.

von Markus K. (markus-)


Lesenswert?

@Gruenschnabel:
Beides braucht ein Takt.
A.K. hat recht, ich habe damit eigentlich Mul und Div gemeint:
imul: 3 Takte
fmul: 1 Takt
idiv: 37 Takte
fdiv: 14 Takte

Das liegt beim Multiplizieren einfach daran, dass er nur einen 16x32 
Multiplizierer hat und deswegen eine 32x32 Multiplikation aus 2x mul und 
1x add zusammensetzen muss.

von Thomas (Gast)


Lesenswert?

1
...
2
#define c_triger 3.3
3
...
4
5
if (3.219 < c_triger) {
6
  mach was...
7
}

Das kann ja bereits zur Compilezeit gelöst werden.
Was der Compiler daraus macht ist also:
1
...
2
mach was...

Floatingpoint führt in aller Regel viel schneller, genauer, fehlerfreier 
und lesbarer zu Ergebnissen als Integer.
Der Hauptgrund, der trotzdem noch für Integer spricht sind die hohen 
Kosten für Controller mit FPU (nur bei hohen Stückzahlen ein Argument).
Die meißten Fälle lassen sich heutzutage allerdings auch prima auf nem 
8-Bitter ohne FPU in Double lösen...

von Markus K. (markus-)


Lesenswert?

Thomas wrote:
> Floatingpoint führt in aller Regel viel schneller, genauer, fehlerfreier
> und lesbarer zu Ergebnissen als Integer.

Darum ging es in der Diskussion doch gerade. FP ist nicht zwangsläufig 
genauer. Ein 32Bit-Integer bietet mehr Genauigkeit als 32Bit-Float, da 
letzterer nur 23Bit Mantisse hat.

Konkretes Beispiel: Ich musste den Durchschnitt aus einer Million Zahlen 
bilden, die einen Wertebereich von +-40 haben. Das kann man nicht ohne 
Trickserei (Zwischenergebnisse) mit 32Bit-Floats rechnen, aber sehr wohl 
mit 32Bit Integern. 64Bit-Floats durfte ich nicht verwenden.

> Der Hauptgrund, der trotzdem noch für Integer spricht sind die hohen
> Kosten für Controller mit FPU (nur bei hohen Stückzahlen ein Argument).
> Die meißten Fälle lassen sich heutzutage allerdings auch prima auf nem
> 8-Bitter ohne FPU in Double lösen...

Der avr-gcc kann kein double.

von Johannes M. (johnny-m)


Lesenswert?

Markus Kaufmann wrote:
> Der avr-gcc kann kein double.
Kleine Ergänzung: Er kann mit dem Datentyp double arbeiten, allerdings 
ist sizeof(double) == sizeof(float) == 4, weshalb double keinerlei 
Vorteile bietet.

von (prx) A. K. (prx)


Lesenswert?

Nicht wirklich. Denn obzwar er "double" als Typ akzeptiert, ist das im 
Sinn des C Standards kein "double", weil zu wenig Stellen.

von Johannes M. (johnny-m)


Lesenswert?

A. K. wrote:
> Nicht wirklich. Denn obzwar er "double" als Typ akzeptiert, ist das im
> Sinn des C Standards kein "double", weil zu wenig Stellen.
Richtig, er heißt nur double. Ist das falsch rübergekommen? Oder 
worauf bezog sich das "nicht wirklich"?

Ich verstehe auch nicht, warum ständig wieder die Diskussion Gleitkomma 
vs. Festkomma aufkommt. Das sind zwei Dinge, die man nicht gegeneinander 
stellen kann, da sie unterschiedliche Anwendungsbereiche haben. Klar, es 
gibt Systeme, die standardmäßig in Gleitkomma rechnen (wie das erwöhnte 
MATLAB), was aber i.d.R. daran liegt, dass der zugrunde liegende 
Prozessor eine FPU hat. Auf Embedded-Systemen, die keine FPU haben (und 
darum ging es ursprünglich), kann man die meisten Dinge sicherlich 
sinnvoll in Festkomma lösen. Aber auch Gleitkommazahlen haben dort ihre 
Daseinsberechtigung, wenn es darum geht, mit Zahlen zu jonglieren, deren 
Wertebereiche sich über mehrere Größenordnungen (d.h. Zehnerpotenzen) 
erstrecken. Dabei ist eine Mantisse-Exponent-Darstellung unschlagbar. 
Man sollte sie nur mit Bedacht eisetzen, aber sicher nicht verteufeln.

Klar, ich kann mir auch selber ein Gleitkommaformat zusammenstricken, 
aber es haben sich zu der Thematik schon viele Leute Gedanken gemacht, 
die Ahnung von der Materie haben und die das sicher effizienter 
hinbekommen...

von P. S. (Gast)


Lesenswert?

Johannes M. wrote:

> Ich verstehe auch nicht, warum ständig wieder die Diskussion Gleitkomma
> vs. Festkomma aufkommt.

Na, z.b. wegen solchen Kommentaren:

"Floatingpoint führt in aller Regel viel schneller, genauer, 
fehlerfreier
und lesbarer zu Ergebnissen als Integer."

Nach der ganzen Diskussion hier hat also jemand immer noch nicht 
verstanden, dass IEEE Fliesskommazahlen eben nicht genau und 
fehlerfrei sind. Und das spiegelt sich leider auch im professionellen 
Umfeld wieder, oft werden Fliesskommazahlen voellig naiv eingesetzt und 
am Ende wird wochenlang nach dem Bug gesucht, der die komischen 
Rechenfehler ausloest.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Peter Stegemann wrote:

> Nach der ganzen Diskussion hier hat also jemand immer noch nicht
> verstanden, dass IEEE Fliesskommazahlen eben nicht genau und
> fehlerfrei sind.

Das steht dort aber auch gar nicht.

Thomas hatte den QA-Aspekt in den Vordergrund gerückt (wie ich weiter
oben auch schon), und solange man mit 23 bit tatsächlicher Genauigkeit
für den jeweiligen Zweck auskommt (bzw. den berühmten 6...7 Dezimal-
stellen), hat er damit gut Recht.

Bezüglich des Aufwandes an Maschinencode dürfte übrigens eine 64-bit-
Integer- oder -Festkomma-Implementierung oft größer ausfallen als
eine 32-bit-Gleitkomma-Implementierung (ist ja auch logisch, sie
bietet ja mehr Genauigkeit).

48 bit Gleitkomma wäre ein sinnvoller Kompromiss (und würde auch die
minimalen Genauigkeitsanforderungen für double gemäß C-Standard
erfüllen), aber da wir hier in einem GCC-Forum sind: GCC unterstützt
leider nur 16-bit-, 32-bit- und 64-bit-Datenformate (und ggf. noch
80 bit oder 128 bit für long long double).

von P. S. (Gast)


Lesenswert?

Jörg Wunsch wrote:

> Peter Stegemann wrote:

>> Nach der ganzen Diskussion hier hat also jemand immer noch nicht
>> verstanden, dass IEEE Fliesskommazahlen eben nicht genau und
>> fehlerfrei sind.
> Das steht dort aber auch gar nicht.

Nun, was steht denn da? Wenn ich es nicht so interpretiere, steht da nur 
ein unhaltbarer Allgemeinplatz.

> Thomas hatte den QA-Aspekt in den Vordergrund gerückt

Was ist der QA-Aspekt?

> (wie ich weiter
> oben auch schon), und solange man mit 23 bit tatsächlicher Genauigkeit
> für den jeweiligen Zweck auskommt (bzw. den berühmten 6...7 Dezimal-
> stellen), hat er damit gut Recht.

Diese Vergleicherei von Bittiefen ist ueberhaupt nicht zielfuehrend. 
Betrachte es am Beispiel von Finanzrechnung, die wir schon angesprochen 
haben. Du hast die Auflage mit einer bestimmten Anzahl von 
Dezimalstellen und festen Rundungsregeln zu rechnen. Die 
Integerimplementation kann die geforderten n Dezimalstellen exakt 
darstellen und auch die Beachtung der Rundungsregeln ist problemlos 
implementierbar. Die IEEE Fliesskommazahl kann nicht einmal 0.1 korrekt 
speichern, das fuehrt zwangsweise zu Rechenfehlern und die sind nicht 
gestattet, auch nicht im Sub-Cent-Bereich. Ganz schnell kracht es, wenn 
Zahlen aus anderen Darstellungen importiert werden. Schon kleinste 
Unterschiede in der Wandlung fuehren dazu, dass zwei Zahlen, die in der 
Ausgabe gleich aussehen, in der internen Darstellung nicht gleich und 
damit auch nicht vergleichbar sind.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Peter Stegemann wrote:

> Nun, was steht denn da?

Dass FP in der Regel viel schneller, genauer und lesbarer zu
Ergebnissen führt.

Es steht dort nicht, dass die Ergebnisse selbst genauer oder die
Rechnung schneller wären.

In vielen Fällen stört es einfach mal gar nicht, nur über eine
geringere Genauigkeit zu verfügen, weil die externe Verarbeitung
vielleicht sowieso nur eine Genauigkeit im Bereich von 1 % oder
so bietet.  Dann ist die Rechengenauigkeit der Gleitkommazahl
mehrere Größenordnungen besser und damit komplett ausreichend
für den Zweck.

>> Thomas hatte den QA-Aspekt in den Vordergrund gerückt
>
> Was ist der QA-Aspekt?

Quality Assurance, die Sicherheit, dass die ursprüngliche Intention
sich auch sauber im geschriebenen (und dann ausgeführten) Code
widerspiegelt.  Bei einer Standardmethode kannst du dich in dieser
Hinsicht erst einmal darauf verlassen, dass deine Werkzeuge ihr
Versprechen halten und eine Implementierung bieten, die in sich
schlüssig und korrekt ist (wobei die Implementierung ihre Grenzen
hat, die man kennen muss, darüber sind sich hier alle einig).

Wenn du eine Nichstandard-Methode nimmst wie Festkommazahlen, dann
musst du dich sowohl um die Qualität der Implementierung selbst als
auch der Umsetzung des Algorithmus kümmern.  Um die Grenzen der
Realisierung musst du dir (ganz genau wie bei Gleitkomma) ohnehin
Gedanken machen, ansonsten handelst du dir mit Über- oder Unterlauf-
Problemen ähnlichen Ärger ein, wie sie dir ein loss of precision
bei Gleitkomma bescheren kann.  In dieser Hinsicht ist die Methode
also keineswegs systembedingt besser.  (Höchstens dahingehend, dass
jemand bei so einer Methode vielleicht eher geneigt ist, diese
Betrachtungen von vornheren mit einzuplanen, während er es bei
Nutzung von Gleitkommazahlen u. U. vergessen könnte.)

von P. S. (Gast)


Lesenswert?

Jörg Wunsch wrote:
> Peter Stegemann wrote:

>> Nun, was steht denn da?
> Dass FP in der Regel viel schneller, genauer und lesbarer zu
> Ergebnissen führt.
> Es steht dort nicht, dass die Ergebnisse selbst genauer oder die
> Rechnung schneller wären.

Sorry, aber worauf soll sich denn die Genauigkeit und die Fehlerfreiheit 
beziehen, wenn nicht auf das Ergebnis?

> In vielen Fällen stört es einfach mal gar nicht, nur über eine

Das ist, genauso wie "in der Regel" eine rein subjektive Angelegenheit. 
In meinem Umfeld ist das zum Beispiel ganz anders, da wird in der 
Regel Exaktheit erwartet. Deswegen sind solche Aussagen hoechst 
ungeschickt.

> Quality Assurance, die Sicherheit, dass die ursprüngliche Intention
> sich auch sauber im geschriebenen (und dann ausgeführten) Code
> widerspiegelt. Bei einer Standardmethode kannst du dich in dieser
> Hinsicht erst einmal darauf verlassen, dass deine Werkzeuge ihr
> Versprechen halten und eine Implementierung bieten, die in sich
> schlüssig und korrekt ist (wobei die Implementierung ihre Grenzen
> hat, die man kennen muss, darüber sind sich hier alle einig).

Dafuer muss man aber auch exakt wissen, was die bestehende 
Implementation verspricht. Das trifft aber bei Fliesskommazahlen auf 
viele Entwickler und erst Recht auf viele Tester absolut nicht zu.

von Gast (Gast)


Lesenswert?

Vlt mal eine kleine Geschichte, wie man auf die Schnautze fallen kann 
mit floats ...

Hatte mal eine map<float> verwendet ... Die ersten schreine 
wahrscheinlich schon gg

Haufen Werte zugewiesen - der Key war dabei immer ein Winkel ...

Und bei:
1
for (float d=0.0f; d<360.0f; d+=1.5f)
2
{
3
  float val = mymap[d];
4
  ...
5
}

kamen ganz merkwürdige Sachen raus gg. Hat mich Stunden gekostet das 
zu finden!

Manchmal lernt man es nur sooo!

Grüße
Gast

von P. S. (Gast)


Lesenswert?

Hm, mit einer Map die interpolieren kann bestimmt nuetzlich. ;-)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Peter Stegemann wrote:

> Sorry, aber worauf soll sich denn die Genauigkeit und die Fehlerfreiheit
> beziehen, wenn nicht auf das Ergebnis?

Auf die Implementierung, das heißt auf die Umsetzung der Aufgabe in
den Code.  Das ist der Gegenstand von QA.

von P. S. (Gast)


Lesenswert?

Jörg Wunsch wrote:
> Peter Stegemann wrote:

>> Sorry, aber worauf soll sich denn die Genauigkeit und die Fehlerfreiheit
>> beziehen, wenn nicht auf das Ergebnis?
> Auf die Implementierung, das heißt auf die Umsetzung der Aufgabe in
> den Code.  Das ist der Gegenstand von QA.

Guter Code + falsches Ergebnis == Alles o.k.?

Ich verstehe nicht, wieso hier eine Diskussion um die Tauglichkeit / 
Ungenauigkeit von Zahlenformaten auf eine ueber Codequalitaet umgebogen 
wird. Thomas hatte auch nirgends QA oder Implementierungsprobleme 
erwaehnt, mir ist wirklich unklar, wieso du das so interpretierst.

Im Uebrigen gab es ja schon spektakulaere FPU-Fehler - wer QA ernst 
nimmt, muesste also auch das testen!

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Peter Stegemann wrote:

> Thomas hatte auch nirgends QA oder Implementierungsprobleme
> erwaehnt, mir ist wirklich unklar, wieso du das so interpretierst.

Weil er es genau so geschrieben hat.

Du interpretierst es nur so (meiner Meinung nach falsch), dass es
wieder in dein Weltbild ("Gleitkomma ist böse") passt.

> Im Uebrigen gab es ja schon spektakulaere FPU-Fehler - wer QA ernst
> nimmt, muesste also auch das testen!

Du meinst den ollen Pentium-Bug vor X Jahren?

Als ob das der einzige jemals vorhanden gewesene CPU-Bug wäre...
Selbst, wenn man mal nur beim Intellismus bleibt, war der F00F-Bug
weitaus dramatischer.

von P. S. (Gast)


Lesenswert?

Jörg Wunsch wrote:
> Peter Stegemann wrote:

>> Thomas hatte auch nirgends QA oder Implementierungsprobleme
>> erwaehnt, mir ist wirklich unklar, wieso du das so interpretierst.
> Weil er es genau so geschrieben hat.

Ich hatte bisher angenommen, man koennte mit dir Sachdiskussionen 
fuehren. Ich frage dich nicht umsonst, warum du das so interpretierst, 
das es fuer mich nicht so klar ist, dass er sich auf QA bezogen hat 
(was er auch nicht erwaehnt hat).

> Du interpretierst es nur so (meiner Meinung nach falsch), dass es
> wieder in dein Weltbild ("Gleitkomma ist böse") passt.

Solche Kommentare sind ueberfluessig und kontraproduktiv.

Hast du mein Finanzbeispiel verstanden?

von Investmentbanker (Gast)


Lesenswert?

> Thomas hatte den QA-Aspekt in den Vordergrund gerückt (wie ich weiter
> oben auch schon), und solange man mit 23 bit tatsächlicher Genauigkeit
> für den jeweiligen Zweck auskommt (bzw. den berühmten 6...7 Dezimal-
> stellen), hat er damit gut Recht.

Nein, hat er nicht. Auch wenn ich genügend Bits habe um den Wertebereich 
abzudecken sind nicht alle Zahlen mit einem float darstellbar. Z.B. wird 
0.1 nur als Näherung abgelegt und nicht exakt. Und wenn du auf meinem 
Konto Buchungen machst dann bitte mit exakten Zahlen und nicht mit 
gerundeten Werten!

> Dass FP in der Regel viel schneller, genauer und lesbarer zu
> Ergebnissen führt.
> Es steht dort nicht, dass die Ergebnisse selbst genauer oder die
> Rechnung schneller wären.

Was bitte ist der Nutzen von schnell geschriebenem Code der zu falschen 
Ergebnissen führt? QA prüft das Ergebnis des ausgeführten Codes, nicht 
den Code selbst. Denen ist es egal wie der Code aussieht, er muss nur 
funktinieren. Da zu erklären dein Code wäre schöner und einfacher wird 
dir nicht die benötigte Unterschrift bei der Abnahme verschaffen.

von Oliver (Gast)


Lesenswert?

Juhu, Ingenieure gegen Controller. Karohemdträger gegen Erbsenzähler.

Inzwischen sollte doch auch nun wirklich klar sein, daß "genau" in der 
Finanzwelt eine andere Bedeutung hat, als in der technischen Welt. Nicht 
umsonst reden die einen Cobol, und die anderen Fortran, mit den 
entspreched passenden Datentypen. Und das schon, seit es Computer gibt. 
Die Geschichte vom Bankangestellten, der sich die Rundungsdifferenzen 
der ganze Bank heimlich aufs eigene Konto gebucht hat, ist auch schon 
aus dem letzten Jahrtausend.

Für Finanzer ist float böse, für Techniker unverzichtbar. Beides nicht 
per se, sondern aus dem jeweiligen Anwendungsgebiet heraus. Ich kriege 
auch mit einem Schraubendreher keinen Nagel in die Wand, trotzdem 
schraubt der Zimmermann mit dem Hammer. Der Schlosser wiederum nicht.

So what?

>Auch wenn ich genügend Bits habe um den Wertebereich
>abzudecken sind nicht alle Zahlen mit einem float darstellbar. Z.B. wird
>0.1 nur als Näherung abgelegt und nicht exakt.

Jau. War so, ist so, und wird immer so sein. Trotzdem hat das Format 
seine Berechtigung und ist, in der richtigen Anwendung richtig 
eingesetzt, unverzichtbar.

Oliver

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Investmentbanker wrote:

> Nein, hat er nicht. Auch wenn ich genügend Bits habe um den Wertebereich
> abzudecken sind nicht alle Zahlen mit einem float darstellbar. Z.B. wird
> 0.1 nur als Näherung abgelegt und nicht exakt.

Es geht um mehr als nur Geld.  Dass dafür Gleitkommazahlen schlecht
brauchbar sind, war bereits diskutiert worden.  (Bei Wechselkursen
wird das schon anders, denn dort kommst du mit Festkomma u. U. in
das gleiche Dilemma, weil du vielleicht deinen einen Euro nicht mehr
exakt auf 4,41302862 Zloty abbilden kannst.)

Bei einem LC-Meter, das von 0,5 pF bis 100 µF alles messen können
soll, hast du aber mit Festkommadarstellungen ziemlich schlechte
Karten.  Dafür interessiert es dich dort überhaupt nicht, ob die
angezeigten 53.12 pF nun intern nur mit einem Rundungsfehler
dargestellt werden können oder nicht.

Jeder Aufgabe ihr Werkzeug.

(Was Thomas denn nun wirklich gemeint hat, kann er nur selbst
erklären.)

von Oliver (Gast)


Lesenswert?

>Bei einem LC-Meter, das von 0,5 pF bis 100 µF alles messen können
>soll, hast du aber mit Festkommadarstellungen ziemlich schlechte
>Karten.

full ack...

...ausser daß das jezt genau DAS klassische Mikrocontrollerbeispiel ist, 
bei dem (je nach Meßprinzip) floats nicht gebraucht werden :-)


Oliver

von Investmentbanker (Gast)


Lesenswert?

> Es geht um mehr als nur Geld.  Dass dafür Gleitkommazahlen schlecht
> brauchbar sind, war bereits diskutiert worden.  (Bei Wechselkursen
> wird das schon anders, denn dort kommst du mit Festkomma u. U. in
> das gleiche Dilemma, weil du vielleicht deinen einen Euro nicht mehr
> exakt auf 4,41302862 Zloty abbilden kannst.)

Habe ich nicht, weil Währungen mit einer festen Anzahl Nachkommastellen 
gehandelt werden :) Obiges Beispiel kommt in der Praxis also nicht vor. 
Der Rundungsfehler bei der Verwendung von floats (oder auch doubles) ist 
aber gerade in dem Bereich hoch relevant, da die gehandelten Summen oft 
hunderte von Millionen betragen. Selbst kleine Fehler sind da schnell 
viel Geld.

von P. S. (Gast)


Lesenswert?

Jörg Wunsch wrote:
> Investmentbanker wrote:

>> Nein, hat er nicht. Auch wenn ich genügend Bits habe um den Wertebereich
>> abzudecken sind nicht alle Zahlen mit einem float darstellbar. Z.B. wird
>> 0.1 nur als Näherung abgelegt und nicht exakt.
> Es geht um mehr als nur Geld.

Meine Guete, das ist ein einfach nachvollziehbares Beispiel, um das 
eigentliche Problem mit Fliesskomma zu erklaeren und ein sehr gutes, 
wenn es darum geht zu zeigen, dass man nicht jedes Genauigkeitsproblem 
mit mehr Bits loesen kann.

> (Bei Wechselkursen
> wird das schon anders, denn dort kommst du mit Festkomma u. U. in
> das gleiche Dilemma, weil du vielleicht deinen einen Euro nicht mehr
> exakt auf 4,41302862 Zloty abbilden kannst.)

Das hast du schonmal gesagt, es bleibt aber falsch. Du kannst zwar einen 
Wechselkurs zwischen beliebigen Waehrungen ausrechnen und dann hast du 
dieses Problem, dieser Kurs dient aber lediglich zur Darstellung, nicht 
zur Konvertierung. Konvertiert wird immer ueber eine Referenzwaehrung 
und da hast du dann auf n Stellen festgelegte, exakte Kurse.

> Jeder Aufgabe ihr Werkzeug.

Schoen, dass wir uns nun einig sind. Was die Poebelei zwischendrin 
sollte, frage ich mich immer noch. Traurig.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Oliver wrote:

> ...ausser daß das jezt genau DAS klassische Mikrocontrollerbeispiel ist,
> bei dem (je nach Meßprinzip) floats nicht gebraucht werden :-)

Naja, 2 * PI (für die Thomsonsche Schwingungsgleichung) lassen sich
mit keiner Computerzahlendarstellung exakt darstellen...  Zumindest
machen die floats hier das Leben deutlich einfacher.

Peter Stegemann wrote:

> Konvertiert wird immer ueber eine Referenzwaehrung
> und da hast du dann auf n Stellen festgelegte, exakte Kurse.

Dann ist natürlich klar, dass ein scaled integer die einzig brauchbare
Lösung ist.  Allerdings muss man den dann wohl dezimal skalieren, also
nicht im Sinne des  ISO/IEC TR 18037:

http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1169.pdf

von Simon K. (simon) Benutzerseite


Lesenswert?

Jörg Wunsch wrote:
> Naja, 2 * PI (für die Thomsonsche Schwingungsgleichung) lassen sich
> mit keiner Computerzahlendarstellung exakt darstellen...  Zumindest
> machen die floats hier das Leben deutlich einfacher.

2*PI lässt sich aber mit gar keiner Darstellung exakt darstellen :-)

von Oliver (Gast)


Lesenswert?

>Konvertiert wird immer ueber eine Referenzwaehrung
>und da hast du dann auf n Stellen festgelegte, exakte Kurse.

Radio Eriwan...

In der betrieblichen Praxis gehen Wechselkursumrechnungen dann trotzdem 
so durcheinander (schon aus dem Grund, weil "den" Wechselkurs für eine 
Währung gar nicht gibt, sondern mehrere, je nach Aufgabestellung), daß 
selbst der pingeligste Buchhalter irgendwann fünf gerade sein lässt, und 
die enstandenen Abweichungen unter "Umrechnungsdifferenz" bucht. Das 
macht das Ssytem dann aber pflichtgemäß in Festkommadarstellung :-)

Oliver

von Roger S. (edge)


Lesenswert?

Gast wrote:
> Hatte mal eine map<float> verwendet ... Die ersten schreine
> wahrscheinlich schon *gg*
>
> Haufen Werte zugewiesen - der Key war dabei immer ein Winkel ...

floats als key in einer map klappt bestens wenn man mit upper_bound 
darin sucht.

Cheers, Roger

von Falk W. (dl3daz) Benutzerseite


Lesenswert?

Simon K. wrote:
> Jörg Wunsch wrote:
>> Naja, 2 * PI (für die Thomsonsche Schwingungsgleichung) lassen sich
>> mit keiner Computerzahlendarstellung exakt darstellen...  Zumindest
>> machen die floats hier das Leben deutlich einfacher.
>
> 2*PI lässt sich aber mit gar keiner Darstellung exakt darstellen :-)

Hast Du doch gerade. In ASCII geht alles ;-)

Falk
P.S.: PI=3243F6A8885A308D3>>64

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Peter Stegemann wrote:

> Diese Vergleicherei von Bittiefen ist ueberhaupt nicht zielfuehrend.
> Betrachte es am Beispiel von Finanzrechnung, die wir schon angesprochen
> haben. Du hast die Auflage mit einer bestimmten Anzahl von
> Dezimalstellen und festen Rundungsregeln zu rechnen. Die
> Integerimplementation kann die geforderten n Dezimalstellen exakt
> darstellen und auch die Beachtung der Rundungsregeln ist problemlos
> implementierbar. Die IEEE Fliesskommazahl kann nicht einmal 0.1 korrekt
> speichern, das fuehrt zwangsweise zu Rechenfehlern und die sind nicht
> gestattet, auch nicht im Sub-Cent-Bereich. Ganz schnell kracht es, wenn
> Zahlen aus anderen Darstellungen importiert werden. Schon kleinste
> Unterschiede in der Wandlung fuehren dazu, dass zwei Zahlen, die in der
> Ausgabe gleich aussehen, in der internen Darstellung nicht gleich und
> damit auch nicht vergleichbar sind.

Dafür gibt es für die Finanzwelt extra die IEEE 854, welche inzwischen 
Teil der IEEE 754r ist.

Damit ist auch 0.1 exakt darstellbar.

Johann

von (prx) A. K. (prx)


Lesenswert?

Und deshalb gibt es Rechnerarchitekturen, die Fliesskommaarithmetik auf 
Basis 10 in Hardware unterstützen.

von yalu (Gast)


Lesenswert?

Welches Darstellungsformat verwendet wird, hängt vor allem von der Art
der darzustellenden Werte ab:


1  Kontinuierliche Werte:

Die Darstellung mit endlich vielen Bytes führt zu einer Granularität >0
und damit zu einem unvermeidlichen Fehler.

Soll der absolute Fehler optimiert werden, wählt man ein Festkomma-
format. Beispiel: Koordinaten von Bohrpositionen. Grund: Die Genauigkeit
der Positionen soll nicht von deren Abstand vom Koordinatenursprung
abhängen.

Soll der relative (also prozentuale) Fehler beschränkt sein, wählt man
ein Gleitkommaformat. Beispiel: Die meisten physikalischen Größen, bspw.
Widerstandswerte. Grund: Ein Hochohmwiderstand muss normalerweisee
nicht auf ein Ohm genau angegeben werden, bei einem Shunt hingegen ist
ein Fehler von einem Ohm schon zu viel.

In beiden Fällen kann mit größeren Bitbreiten der Fehler reduziert
werden, allerdings auf Kosten des Speichers.


2  Diskrete Werte:

Bei konstanter Schrittweite skaliert man die Werte so, dass sie als
Ganzzahlen darstellbar sind. Dann ist der Darstellungsfehler gleich
null.

Bei Bargeldbeträgen in einer gegebenen Währung wählt man also sinnvol-
lerweise einen Skalierungsfaktor von 100. Diese Darstellung ist aber
nicht überall im Finanzwesen sinnvoll. Jörg  nannte schon das Beispiel
mit unterschiedlichen Währungen. Ein anderes Beispiel sind die US-ameri-
kanischen Aktienkurse von vor 2001, die in Vielfachen von 0,0625 Dollar
angegeben wurden, was mit einem Skalierungsfaktor von 16 in den ganz-
zahligen Bereich transformiert werden kann. Wenn Bargeldbeträge und
Aktienkurse im gleichen Format dargestellt werden sollen, würde man 400
als Skalierungsfaktor wählen.


Außer der Art der darzustellenden Werte spielen aber auch andere Aspekte
eine Rolle, die größtenteils schon genannt wurden, wie bspw. die Ausfüh-
rungsgeschwindigkeit und die Entwicklungszeit. Hier sind noch ein paar
weitere:

- Die meisten Programmiersprachen bieten keine Datentypen und Rechen-
  operationen für Festkommazahlen.

- Mathematische Funktionen wie sin(), log() u.ä. sind meist nur für
  Gleitkommazahlen verfügbar.

- Gleitkommazahlen sind oft nur in einer oder zwei Bitbreiten verfügbar
  und sind damit für manche Anwendungen entweder zu ungenau oder zu
  speicherintensiv.

- Fehler enstehen nicht nur durch die Darstellung, sondern auch bei den
  Berechnungen. Je nach verwendetem Datenformat sind bestimmte Rechen-
  operationen genau und andere ungenau.

Man kann sich fehlende Features zwar immer selbst zusammenbasteln, aber
dann droht eben wieder der Time-To-Market-Aspekt.

Die Kunst bei der Auswahl des Datenformats ist es nun, den nach allen
genannten Gesichtspunkten besten Kompromiss zu finden. Pauschalisierende
Auswahlregeln führen meist am Ziel vorbei, Denken ist angesagt :)

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Zum allgemeinen Interesse sei noch angemerkt, daß es neben den 
Darstellungen "Ganzzahl", "Gleitkommazahl", "Fixpunktzahl" noch andere 
Darstellungen nebst Arithmetik gibt, etwa mit folgenden Eigenschaften.

1) Erlaubte Eingaben sind ganze Zahlen
2) Erlaubte Operationen sind +, -, *, / und Quadratwurzel

Dann lässt sich für einen Werte a, der aus der Eingabe durch Anwendung 
der Operationen hervorgeht, exakt — also ohne Rundungsfehler — 
entscheiden, ob a = 0, a < 0 oder a > 0 gilt!

Wem die Niederungen des Börsenparketts oder der Ganzzahl-Arithmetik fern 
sind, kann ja dazu überwechseln ;-)

Johann

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.