www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Berechnungen mit µC in ANSI C


Autor: Daniel Xxx (daniel_78)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo User,

kann mir evtl. jemand helfen bei ANSI C für meinen µC.

Ich möchte etwas berechnen und habe folgendes deklariert:

volatile unsigned int AN6;      // 0 ….65565
volatile unsigned int AN6_1;    // 0 ….65565
volatile unsigned int AN6_2;    // 0 ….65565
volatile unsigned int AN6_3;    // 0 ….65565
volatile float Ergebnis;      // Gleitkomma

Ergebnis = ((AN6 + AN6_1 + AN6_2 + AN6_3)/4) * 0.2356 – 85,66

Wie schreibe ich die Formel richtig in ANSI C?

Ich benutze den C18 Compiler von Microchip.

Besten Dank.

Daniel

Autor: Johannes Schmid (jhs)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi!
unsigned int ZwischenErgebnis = AN6 + AN6_1 + AN6_2 + AN6_3; // evtl. auch uint32_t falls das Ergebnis größer als 65565 ist
Ergebnis = (float) (ZwischenErgebnis / 4) * 0.2356 - 85.66;

Natürlich kannst du auch ohne die temporäre Variable auskommen, aber 
dann wirds unübersichtlich. Ich denke du weißt ja, was bei der Addition 
rauskommt also kannst du da auch einen gutem Namen vergeben.

Eigentlich ist der C Compiler davon auch recht unabhängig, so lange er 
ANSI C sauber implementiert. Denk dran, dass du vielleicht noch die libm 
mit einlinken musst, weil dein uC hat wahrscheinlich keine FPU.

Gruß
Johannes

Autor: B e r n d W. (smiley46)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Term (ZwischenErgebnis / 4) wird noch als unsigned int durchgeführt 
und dabei wird gerundet, die Nachkommastellen gehen verloren.
Dann wenigstens so: ((float)ZwischenErgebnis / 4)

Oder gleich so:
Ergebnis = (((float)AN6 + AN6_1 + AN6_2 + AN6_3)/4) * 0.2356 – 85.66;

Gruß, Bernd

Autor: Michael H. (morph1)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ergebnis = ((float)(AN6 + AN6_1 + AN6_2 + AN6_3)/4) * 0.2356 – 85.66;

wenn dann müssen die klammern schon richtig sitzen ;)

Autor: B e r n d W. (smiley46)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Michael H.
Das spart eventuell ein wenig Rechenzeit, da erst 3 Additionen per 
unsigned int durchgeführt werden und dann erst gecasted. Falls die Summe 
der vier ANs größer als 65565 werden kann, müßte man zuerst nach (long) 
casten, dann addieren, dann nach (float) casten und dann erst /4 
dividieren.

Falls es sich um eine zeitkritische Berechnung handelt, könnte man noch 
weiter optimieren und eventuell ganz auf float verzichten. Mir 
persönlich ist es lieber, wenn die Float-Library nicht eingebunden 
werden muß.

Gruß, Bernd

Autor: Rolf Magnus (rmagnus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Falls die Summe der vier ANs größer als 65565 werden kann, müßte man
> zuerst nach (long) casten, dann addieren, dann nach (float) casten und
> dann erst /4 dividieren.

Oder man schiebt das /4 nach hinten zum anderen Faktor, dann kann man 
sich den Cast sparen, und man hat die besten Chancen, daß diese Division 
schon zur Compilezeit gemacht wird:
Ergebnis = ((unsigned long)AN6 + AN6_1 + AN6_2 + AN6_3) * (0.2356 / 4)  85.66;

Autor: Maik Werner (werner01)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sevus ,


ich habe die erfahrung gemacht beim hitech comiler das wenn ich a=a+2
schreibe er dann weniger code erzeugt als wenn ich a +=2?

warum ist das so?




mfg

Autor: der mechatroniker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Optimierungen vergessen einzuschalten?
Ansonsten: Compiler ist schrott.

Autor: Daniel Xxx (daniel_78)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo User,

vielen Dank für die vielen Antworten. Bei der Addition ist der Wert 
übrigens kleiner als 65565.

Ich werde den Code heute Abend gleich mal änden und testen/schauen was 
geht.

Vielen Dank erst einmal uns schönen Sonntag noch.

Daniel

Autor: Walter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn du nur Int brauchst, und es optimierten müsstest, dann wäre der Weg 
folgender:

unsigned int32 T;
T =(AN6 + AN6_1 + AN6_2 + AN6_3); T/=4; T *= 15440; T-=5613813;
Ergebnis = T>>16 // oder union high short byte von unsigned int.
Eventuell
Ergebnis = (uint16)((((uint32)(AN6 + AN6_1 + AN6_2 + AN6_3)/4 * 
(uint16)(256*256*.2356) ) - (uint32)(256*256*85.66))>>16)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.