Forum: Mikrocontroller und Digitale Elektronik Fließkomma mit Mega16 und avr gcc


von XYZ (Gast)


Lesenswert?

Hallo zusammen,

ich möchte mit einem Mega 16 Fließkomma-Berechnungen durchführen und 
habe dazu ein paar Fragen, da ich im Netz nichts eindeutiges dazu finden 
konnte:

-Wie genau ist die Fließkomma-Berechung mit double und float, bzw. sind 
diese Typen tatsächlich identisch in avr-gcc, also wie viele 
Nachkommastellen werden berücksichtigt? Beim direkten Eingeben der 
Nachkommastellen scheinen die Zahlen wesentlich genauer zu sein, als vom 
Mikrocontroller errechnete Werte. Kann es sein dass der Compiler bei 
komplizierteren Berechnungen einfach weniger Stellen berechnet?

-Kann man in avr-gcc arrays mit 32 oder 64 Bit Variablen bilden, also 
mit uint_32 oder unint_64, oder funktionieren nur 8 bit arrays? Wie groß 
kann ein Array maximal werden, bzw. ist die maximale grüße nur durch den 
Flash-Speicher begrenzt?

Ich hatte ein perfekt funktionierendes Programm mit einem aus 500 Bytes 
bestehendem Array und einer Gesamtgröße von 3 kByte. Lediglich durch das 
Einfügen eines Arrays aus 2000 float Variablen funktionierte das 
Programm plötzlich nicht mehr, obwohl die Gesamtgröße ca. 11 kByte war. 
Der Compiler zeigte jedoch keinen Fehler an.

Vielen Dank schonmal für eure Hilfe

von Peter D. (peda)


Lesenswert?

XYZ schrieb:
> Lediglich durch das
> Einfügen eines Arrays aus 2000 float Variablen

Schau mal ins Datenblatt, wieviel SRAM der Mega16 hat.
float = double = 4 Byte groß.

unint_64 nur dann nehmen, wenn für das Programm Schneckentempo ausreicht 
und die Codegröße völlig egal ist.
Ist nämlich extrem ineffizient implementiert.


Peter

von Karl H. (kbuchegg)


Lesenswert?

XYZ schrieb:

> -Wie genau ist die Fließkomma-Berechung mit double und float, bzw. sind
> diese Typen tatsächlich identisch in avr-gcc,

Erst mal: Mit dem WinAvr, also dem freien gcc Compiler, sind auf einem 
AVR float und double tatsächlich gleich groß: 4 Bytes
Das ist aber vom Compiler abhängig. Andere Compiler mögen das anders 
sehen.

> also wie viele
> Nachkommastellen werden berücksichtigt?

Die Anzahl der Nachkommastellen ist bei Floating Point uninteressant. 
Wichtig ist, wieviele signifikante Stellen (also Stellen insgesammt) du 
zur Verfügung hast. Bei float geht man von ungefähr 5 bis 6 
signifikanten Stellen aus.
Dh. die Zahl 1234.56
wird noch einigermassen sauber darstellbar sein. Eventuell ist auch die 
3. Nachkommastelle noch brauchbar (ja nachdem wie die Vorgeschichte der 
Zahl aussah), aber alles dahinter ist dann mehr oder weniger nur noch 
gelogen.


> Beim direkten Eingeben der
> Nachkommastellen scheinen die Zahlen wesentlich genauer zu sein, als vom
> Mikrocontroller errechnete Werte.

Das ist ziemlich normal.
Mit jedem Rechenvorgang verlierst du ein bischen was (*)

Rechnen mit Floating Point ist wie das Umschaufeln eines Sandhaufens.
Je öfter man es macht, desto mehr Sand verliert man und desto mehr 
Schmutz bekommt man.

> Kann es sein dass der Compiler bei
> komplizierteren Berechnungen einfach weniger Stellen berechnet?

Nein. Es wird immer mit der gleichen Bitzahl gerechnet. Aber es ist nun 
mal das Wesen von Floating Point, dass sie nur eine Näherung dessen 
sind, was du in der Mathematik als rationale Zahlen kennst.


Im Normalfall sollte man sich auf einem µC sehr gut überlegen, ob man 
überhaupt Floating Point benutzen will. Meistens ist es unnötig.

> Ich hatte ein perfekt funktionierendes Programm mit einem aus 500 Bytes
> bestehendem Array und einer Gesamtgröße von 3 kByte. Lediglich durch das
> Einfügen eines Arrays aus 2000 float Variablen funktionierte das
> Programm plötzlich nicht mehr, obwohl die Gesamtgröße ca. 11 kByte war.

Da wirst du wohl irgendwo einen Fehler gemacht haben, bzw. die 
Gesamtgröße deines Programms ist größer als ein techologisches Limit 
geworden (Flash, SRAM, ... )

> Der Compiler zeigte jedoch keinen Fehler an.

Das ist dem Compiler auch normalerweise egal. Wenn überhaupt, dann 
interessiert das den Linker. Aber im Normalfall ist es dein Bier dafür 
zu Sorgen, dass du alles im Speicher unterbringst.


(*) wobei sich dieses 'bischen was' je nach konkreten Zahlenwerten auch 
mächtig aufblähen kann.

von Falk B. (falk)


Lesenswert?

@  XYZ (Gast)

>-Wie genau ist die Fließkomma-Berechung mit double und float, bzw. sind
>diese Typen tatsächlich identisch in avr-gcc, also wie viele
>Nachkommastellen werden berücksichtigt?

5 bis 6.

>Mikrocontroller errechnete Werte. Kann es sein dass der Compiler bei
>komplizierteren Berechnungen einfach weniger Stellen berechnet?

Der Compiler nicht, der AVR.

>-Kann man in avr-gcc arrays mit 32 oder 64 Bit Variablen bilden, also
>mit uint_32 oder unint_64,

Ja, sind aber recht langsam, da nicht optimiert.

> oder funktionieren nur 8 bit arrays?

Nein.

>Wie groß
>kann ein Array maximal werden, bzw. ist die maximale grüße nur durch den
>Flash-Speicher begrenzt?

Schon mal über das Thema Speicher nachgedacht?
Ein variables Array kann manxima so gross wie der SRAM werden, ein 
konstantes Array so groß wie der Flash. Eigentlich logisch, oder?
Allerdings muss man das beim AVR gesondert handhaben, siehe

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Speicherzugriffe

>Ich hatte ein perfekt funktionierendes Programm mit einem aus 500 Bytes
>bestehendem Array und einer Gesamtgröße von 3 kByte. Lediglich durch das
>Einfügen eines Arrays aus 2000 float Variablen funktionierte das
>Programm plötzlich nicht mehr, obwohl die Gesamtgröße ca. 11 kByte war.
>Der Compiler zeigte jedoch keinen Fehler an.

Aber sicher. Der zeigt >100% Speicherauslastung im RAM an. 2000x float = 
8kB. Hmmm.

MfG
Falk

von XYZ (Gast)


Lesenswert?

Hallo zusammen,

vielen Dank für die schnellen und sehr ausführlichen Antworten. Ich 
werde dann doch keine Fließkommawerte benutzen, sondern mit Integern 
rechnen und diese dann dementsprechend mit Zehnerpotenzen "bearbeiten".

Die Arrays werden wohl tatsächlich komplett im Ram abgelegt, selbst wenn 
sie als Konstanten deklariert werden. Der Mega16 hat nämlich nur 1 kByte 
Ram und da haben dann wohl die über 8k Daten nicht hineingepasst.

Ich habe nun die Arrays mit 
http://www.nongnu.org/avr-libc/user-manual/pgmspace.html in den 
Flashspeicher ausgelagert und nun funktioniert alles bestens!!

Nochmals Danke und viele Grüße

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.