Hi an alle. Ich arbeite mit einem atxmgea und dem AVR Studio. Dabei ermittle ich 2 Werte welche ich anschließend miteinander addiere. Bei der Addition wird aber auf 2 Stellen gerundet und ich verstehe nicht warum. Eingaben lauten: vop2E=1 vop2Z=2 vop2H=3 vop2T=4 vop2ZT=5 nop2E=6 nop2Z=7 nop2H=8 Hier der grundlegende Aufbau Teil1: vop2E = vop2E*1; vop2Z = vop2Z*10; vop2H = vop2H*100; vop2T = vop2T*1000; vop2ZT = vop2ZT*10000; vop2_sum = vop2E + vop2Z + vop2H + vop2T + vop2ZT; Hier der grundlegende Aufbau Teil2: nop2E = nop2E*1; nop2Z = nop2Z*10; nop2H = nop2H*100; nop2_sum = nop2E + nop2Z + nop2H; while(nop2_sum>=1) { nop2_sum=nop2_sum/10; } Und hier scheint der Fehler zu passieren: op2_sum = vop2_sum + nop2_sum; Vielleicht kann mir jemand sagen warum hier dieser Rundungsfehler passiert. Ich habe die Tabelle mit den Variablenwerten aus dem AVR Studio angehängt, damit ihr seht welche Variable welchen Wert hat. MUTLIPLIKATION: Hier ist mir noch etwas aufgefallen: Wenn ich 2 Variablen multipliziere, dann wird auch stark gerundet: op1_sum = 48251,172 op2_sum = 63279,938 result = op1_sum * op2_sum; Dies ergibt laut AVR Studio: 3.0533312E+009 Sollte aber laut Windows calc: 3053331076,084992 Bin froh um jede Hilfe. Vielen Dank.
:
Verschoben durch Admin
Wieviele Stellen erwartest du von 32-Bit Fliesskommarechnung? avr-gcc hat keine echten "double" Werte, kennt nur 32-Bit Format. Und das ist gut für ca. 7 Stellen.
Dei Datentypen sind double. in 52bit Mantisse sollten mehr Stellen reinpassen (es sind im Beispiel 24 signifikante Bits nach der 1, auch zuviel für ein single) Da aber die Rechnung fehlt, ist nicht auszuschliessen, dass zwischendurch in single arithmetik was gemacht wurde ...
Vielen Dank für die Antworten. @ Maxx: Welche Rechnung meinst du, die fehlen soll?
Zeig doch einfach dein Programm als Dateianhang.
Naja die eigentliche Rechnung hast du nicht angegeben. Nur beschrieben was du machst, ohne den Code dazu. Man kann einige Dinge ("Fehler") machen, die den numerischen Fehler unnötig erhöhen.
Er hat doch alles angegeben, es geht um op2_sum = vop2_sum + nop2_sum und erwartet mehr als 2 Stellen, meint dabei Nachkommastellen. vop2_sum = 54321 nop2_sum = 0.67800003 Ergebnis auf 7 Dezimalstellen: 54321.68 op2_sum = 54321.68 Für die Muliplikation gilt das ebenfalls. Beide Ergebnisse stimmen auf 7 Stellen überein. Wo ist also das Problem? Works as designed. ANSI-konform ist das nicht, weil da für double 10 Stellen verlangt werden, aber so ist avr-gcc nun einmal gebaut. Wer nicht glaubt, dass sizeof(double)==4, der sehe sich mal die Adressen von vop2ZT und vop2_sum an.
@ A. K. : Das heisst der avr-gcc kann das einfach nicht besser? Vielen Dank.
Genau das heisst es. Ganzzahlig kann er jedoch 64 Bits.
@ A. K. : Vielen Dank für deine Hilfe. Dann ich meine Fehlersuche nun stoppen. :-)
A. K. schrieb: > Für die Muliplikation gilt das ebenfalls. Beide Ergebnisse stimmen auf 7 > Stellen überein. > > Wo ist also das Problem? Works as designed. Noe. nicht wie designed. Designed sind 52 signifikante Bits im double. Das wären 15,6 signifikante Dezimalstellen.
Maxx schrieb: > Noe. nicht wie designed. Designed sind 52 signifikante Bits im double. > Das wären 15,6 signifikante Dezimalstellen. Der Designer von avr-gcc sah das offenbar anders. Dass avr-gcc nicht C89-konform ist schrieb ich oben schon, wobei C89 übrigens keine 52 Mantissenbits verlangt.
Ist ja auch kein Angriff auf dich gewesen, sondern, dass es nicht dem Design entspricht. Die single/double Formate standardisiert das IEEE 754.
Maxx schrieb: > Die single/double Formate standardisiert das IEEE 754. Das hat aber erst seit C99 einen Bezug zu C. Davor nicht. Man kann also nicht darauf vertrauen, dass "double" dem IEEE Format entspricht. Bei 8-Bit Controllern erst recht nicht.
Maxx schrieb: > Ist ja auch kein Angriff auf dich gewesen, sondern, dass es nicht dem > Design entspricht. Welchem "Design"? Bei avr-gcc wurde double mit Absicht nur 32 Bit breit gemacht, also entspricht das dessen Design. Es entspricht vielleicht nicht der C-Spezifikation, aber das ist ja schon bekannt.
A. K. schrieb: > ANSI-konform ist das nicht, > weil da für double 10 Stellen verlangt werden Ich glaube, es wäre sogar ANSI-konform gewesen ;-), es war sogar noch konform zu den ersten Drafts von ISO-C99, die Forderung mit mindestens 10 Stellen Genauigkeit (die bspw. durchaus auch von einem 48-bit-Format erfüllbar wäre, 64 bit sind nirgends vorgeschrieben) kam erst kurz vor dem endgültigen Standard rein.
Wenn ich das richtig sortiere, dann sind die 10 Stellen bereits Bestandteil von ANSI/C89, während C99 effektiv IEEE754 vorschreibt.
C99 schreibt: FLT_DIG 6 DBL_DIG 10 LDBL_DIG 10 als minimale Werte vor. OK, vielleicht habe ich mich auch geirrt, dass es in einem der Drafts nicht so gewesen wäre, ich finde zumindest in den alten, die ich noch habe, nichts mehr. Ist ja auch irrelevant, da der Standard es so vorschreibt wie oben gezeigt. Das macht AVR-GCC derzeit nicht, eine 64-bit-FP-Implementierung zu haben, ist zwar ein frequently requested item, es gab auch schon mal jemanden, der Interesse geäußert hat (und möglicherweise den notwendigen Durchblick in die GCC-Details), das zu machen, aber seither habe ich von ihm auch nur nichts mehr gehört. :(
Wirst recht haben. Ich stolperte letzthin zwar über einen Zusammenhang zwischen C99 und einem IEC Floating-Point Standard, der um's Eck rum auf den IEEE754er rauslief, aber das ist evtl. nicht zwingend. Da unsereiner von solchen Standards grundsätzlich immer nur Drafts zu sehen kriegt, bleibt das eben alles indirekt oder inoffiziell.
A. K. schrieb: > Da unsereiner > von solchen Standards grundsätzlich immer nur Drafts zu sehen kriegt, > bleibt das eben alles indirekt oder inoffiziell. Vom C-Standard gibt's ja zum Glück eine "semi-offizielle" Version: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1336.pdf Die ist zwar als "Draft" (und zwar schon für C1x) markiert, ist aber in Wirklichkeit der Text des offiziellen Standards mit den eingear- beiteten drei technical corrigenda. Für die (etwas bekanntere) Vorgängerversion: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf steht das noch etwas offensichtlicher drüber (Standard + TC1/TC2). Die Mindestwerte deuten meines Erachtens darauf hin, dass man eine 48-bit-Implementierung (8 Bit Exponent, denn nur 1E-37...1E37 ist gefordert und 40 Bit Mantisse) auf jeden Fall damit abgedeckt sehen möchte, nur eben eine 32-bit-Implementierung nicht mehr. Leider dürfte es für den GCC ungleich schwieriger sein, ihm eine 48-bit-Implementierung (für den AVR-GCC) beizubringen denn eine mit 64 bit, da er intern auf einen derartigen Datentypen m. W. nicht vorbereitet ist.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.