mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Division by Zero


Autor: Christian S. (mueke)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,
ich habe in mein Quelltext folgende Berechnung für mein ATMEGA16 
eingeügt und bekomme Warnungen: Division by Zero

Ich weiß aber nicht warum, ich dividiere doch gar nicht durch 0...


MFG
Muecke

Autor: Christian S. (mueke)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, ei wenig durcheinander. Hier natürlich noch der Quelltext:
if(CONFIG.FREQ <= 100 && CONFIG.FREQ != 0)
        OCR1A = ((1/CONFIG.FREQ) / (1/(4000000/64))) / 2;

else if(CONFIG.FREQ > 100 && CONFIG.FREQ <= 255)
  OCR1A = ((1/CONFIG.FREQ) / (1/(4000000/8))) / 2;

else if(CONFIG.FREQ < 255)
  OCR1A = ((1/CONFIG.FREQ) / (1/4000000)) / 2;

Autor: Willi Wacker (williwacker)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Quelltext ?

Autor: T.Stütz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
(1/(4000000/8)) = 0 da nicht als float/double gerechnet !

Gruß

Autor: Timo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich glaube schon:

1/(4000000/64)

müsste eigentlich eine Integeroperation sein, da kommt also Null raus.
Probier es mal mit:

((1.0/CONFIG.FREQ) / (1.0/(4000000.0/64.0))) / 2.0

CONFIG.FREQ muss ein Float sein.

Autor: Johannes Slotta (johanness)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab jetzt mal keine Ahnung, was CONFIG.FREQ ist, vermute aber eine 
Gleitkommavariable dahinter.

Fehler liegt z.B. hier:

1/(4000000/64)

Du dividierst 1 durch einen ziemlich großen Wert. Beides sind 
Ganzzahlen, das Ergebnis ist eine Ganzzahl und wird abgerundet, also auf 
0. Warum invertierst du die Zahl, um dann dadurch zu dividieren? Lass 
das 1/ und mach aus dem / davor ein *.

Autor: Willi Wacker (williwacker)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die letzte Zeile kann erreicht werden wenn CONFIG.FREQ==0 und dann hast 
Du eine Division by Zero

Autor: Christian S. (mueke)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK Danke. ich habe überall ein ".0" angefügt und CONFIG.FREQ gecastet... 
Funktioniert nun

Autor: Timo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Sinn der letzten else if Anweisung erschliesst sich mir aber auch 
nicht. Wofür soll die sein?

Autor: Johannes Slotta (johanness)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Anmerkung nebenbei...

Wäre es für deine Anwendung ungünstig, die Formel

((1/CONFIG.FREQ) / (1/(4000000/64))) / 2;

umzustellen als

(4000000/64)  2  CONFIG.FREQ;

? Ich denke das ist eher das, was du meinst, und die Konstanten am 
Anfang kann ein vernünftiger Compiler auch besser zusammenfassen.

Beschreibe doch mal, was CONFIG.FREQ ist (Ganzzahl, Fließkommazahl, in 
welchem Wertebereich).

Autor: Joerg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es müsste doch reichen, die 4Mio. als "long" zu kennzeichnen ("L" 
anhängen), oder? (besser als zu 'riskieren', dass die Float-Berechnung 
nicht wegoptimiert wird)
hth. Jörg

Autor: Christian S. (mueke)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
CONFIG.FREQ ist definiert als uint16_t.
Also eine 16bit-Zahl. Hiermit sollen die Frequenzen erzeugt werden mit 
Timer1 und es funktioniert jetzt soweit. Mit dem Umstellen werde ich mal 
probieren... Danke...

Autor: Johannes Slotta (johanness)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Immer an Mathe denken: A/(1/B)==A*B
Das erste geht hier durch die Integerarithmetik schief, also warum die 
linke Seite verwenden, wenn die rechte besser geht? Denn die 
Spezialitäten der Integerarithmetik willst du ja eigentlich gar nicht.

Und die if-Abfragen würde ich noch einmal überarbeiten. Besonders das < 
in der letzten Abfrage sollte ein > sein.

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.