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.
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
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.
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...
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.
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:
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
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...
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).
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 :-)
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.
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.
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 :-|
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.
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.
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.
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.
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.
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 ;)
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...
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
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.
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.
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
> 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.
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>
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...
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.
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.
>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?
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.
@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.
Das kann ja bereits zur Compilezeit gelöst werden.
Was der Compiler daraus macht ist also:
1
...
2
machwas...
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...
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.
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.
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...
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.
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).
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.
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.)
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.
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(floatd=0.0f;d<360.0f;d+=1.5f)
2
{
3
floatval=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
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.
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!
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.
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?
> 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.
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
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.)
>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
> 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.
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.
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
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 :-)
>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
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
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
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
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 :)
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