www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Rechen mit großen Zahlenwerten


Autor: tsaG (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, ich möchte in meinem Programm eine Berechnung ausführen (AVRGCC 
20100110, Atmega16) und zwar:
x = ( l*m*100 ) / ( d*a )
mit l=0...500; m=0...1023; d=1...250 a=1...1023

Wie kann ich diese Berechnung am Besten implementieren?

Hab schon diverse Varianten ausprobiert und bekomme im AVR Simulator und 
auf der Zielhardware immer wieder falsche Ergebinsse.

z.B.: für: temp=(uint16_t)((d*a)/1024); liefert der Simulator als 
Ergebnis mit d=250 und a=800 temp=3 obwohl es 195 seien sollten.
Wie bekomme man den Überlauf der Zahlen (d*a) wärend der Berechung in 
den Griff? Kann das der Compiler von sich aus?

Danke für die Hilfe.

Autor: Uwe ... (uwegw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Compiler achtet darauf nicht. Du musst bei ALLEN Zwischenschritten 
selbst prüfen, ob ein Überlauf auftreten kann, und dann die Operanden 
auf den passenden Typ casten. In deinem Fall also auf 32 Bit.

Autor: Peter Diener (pdiener) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das einfachste ist, alle verwendeten Variablen als unsigned long zu 
definieren.
unsigned long x, l, m, d, a;

l = 100;
m =  10;
d =  50;
a =  10;

x = ( l*m*100 ) / ( d*a );

Grüße,

Peter

Autor: tsaG (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo vielen Dank euch Beiden. Hab jetzt in der Berechnung bei den 
Überläufen auf 32bit Variable gecastet und jetzt funktioniert die 
Rechnung. Auf die 2. Variante hätte ich auch selber kommen können....
Schönen Abend noch.

Autor: heinz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ja ja die bösen Integer ;-)

aber mal im ernst, UINT16 => 2^16 => 0..65535

du musst bei deiner Berechnung sicherstellen das der Datenbereich nicht 
überlaufen wird. Dabei verlierst du allerdings an Genauigkeit. (einen 
Tot muss man ja sterben ;-) )

Genrell musst du versuchen durch geschicktes skalieren des Dividenden 
und zerlegen des Divisors innerhalb deiner gegebenen grenzen zu bleibe.

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.