Forum: Compiler & IDEs 16bit multiplikation mit 8bit controller


von Wastl F. (rescuetigerchen)


Lesenswert?

Hallo Gemeinde,
ich versuche mich gerade an einer kleinen Rechenaufgabe.
Controller ist ein Atmega128a (also 8bit)
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <stdint.h>
4
5
int freq;
6
uint16_t i_time, e_time, b_time;
7
8
b_time = ((60000/freq)/3);
9
i_time = b_time;
10
e_time = b_time*2;

Bei freq=1 stimmt der Wert von b_time mit 20000, auch i_time hat 
natürlich den richtigen Wert. Schau ich mir aber e_time an, so zeigt er 
mir einen negativen Wert an. Der Controller scheint die Variable e_time 
als int16_t zu handhaben, denn ab 32767 passiert der Overflow.
Nun habe ich schon Beispiele gefunden, die mit ASM eine Art Workaround 
bilden, nur habe ich von ASM keine Ahnung.
Weiß jemand, ob der MUL-Befehl oder ähnliches mit C umgesetzt werden 
kann?
Danke und Gruß,
wastlB

von Ralf G. (ralg)


Lesenswert?

Da gibt's von Experten sicher noch eine astreine Erklärung.
Mich würde jetzt erstmal die 60000 stören, die ja zwingend uint16 sein 
muss, wenn man bei 16 Bit bleiben will. Das Ganze jetzt durch ein int16 
...

Also es muss schon vor der Zuweisung an e_time was 'schiefgelaufen' 
sein.

von Stefan E. (sternst)


Lesenswert?

Wastl B. schrieb:
> Schau ich mir aber e_time an, so zeigt er
> mir einen negativen Wert an.

Und was genau heißt hier "zeigt er mir an"? Denn sehr wahrscheinlich 
liegt das Problem in dem Teil, und nicht in den gezeigten Zeilen.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Wastl B. schrieb:
> Schau ich mir aber e_time an, so zeigt er mir einen negativen Wert an.

Der Wert von e_time ist richtig (40000), du lässt ihn dir aber falsch
ausgeben (-25536). Deinen Fehler erkennst du schon daran, dass e_time
als uint16_t-Variable per definitionem gar nicht negativ werden kann.

von Wastl F. (rescuetigerchen)


Lesenswert?

ich wandle den wert mit itoa(e_time,num,10) in einen ASCII-String und 
gebe diesen auf einem Display aus.
num ist hier mit num[16] definiert.
Da aber alle Zahlen bis 32767 zuverlässig ausgegeben werden, denke ich 
mir, daß der Fehler schon vor dem itoa() liegen muss.

von Wastl F. (rescuetigerchen)


Lesenswert?

meine güte...
klarer fall von "poste den ganzen code"...
ein utoa() hat das problem gelöst.
danke an alle!

von Yalu X. (yalu) (Moderator)


Lesenswert?

Es wird Zeit, dass sich endlich Programmiersprachen durchsetzen, die
keine implizite Typumwandlung vorsehen, zumindest keine solchen, die den
Wert verändern. In diesem Fall wäre damit eine Fehlermeldung ausgegeben
worden, weil für ein signed-Argument eine unsigned-Variable übergeben
worden ist.

Ich verstehe aber auch nicht, warum der GCC für diesem Fall nicht
wenigstens eine zuschaltbare Warnung bereit hält. Für jeden anderen,
kaum fehlerträchtigen Mist wie bspw.

  a && b || c

statt

  (a && b) || c

wird bei -Wall eine nervige Warnung ausgegeben (die man zum Glück
abschalten kann).

von Rolf M. (rmagnus)


Lesenswert?

Yalu X. schrieb:
> Es wird Zeit, dass sich endlich Programmiersprachen durchsetzen, die
> keine implizite Typumwandlung vorsehen, zumindest keine solchen, die den
> Wert verändern. In diesem Fall wäre damit eine Fehlermeldung ausgegeben
> worden, weil für ein signed-Argument eine unsigned-Variable übergeben
> worden ist.
>
> Ich verstehe aber auch nicht, warum der GCC für diesem Fall nicht
> wenigstens eine zuschaltbare Warnung bereit hält.

Du meinst so wie er es mit -Wconversion tut? Stimmt, das verstehe ich 
auch nicht ;-)

von Yalu X. (yalu) (Moderator)


Lesenswert?

Rolf Magnus schrieb:
> Du meinst so wie er es mit -Wconversion tut? Stimmt, das verstehe ich
> auch nicht ;-)

Ja, genau das habe ich vermisst. Vielen Dank für den Hinweis!

Dann verstehe aber etwas anderes nicht, nämlich warum -Wconversion nicht
in -Wall, ja nicht einmal in -Wextra enthalten ist. Ok, laut Anleitung
gehören implizite Typumwandlungen mit Änderung des Werts wohl zu denen,

  "that users generally do not consider questionable"

Zu diesen Usern gehöre ich definitiv nicht. Dafür halte ich die meisten
der durch -Wparentheses abgedeckten Konstrukte für überhaupt nicht
questionable.

Aber gut, solange man die Warnungen einzeln ein- und ausschalten kann,
ist das kein großes Problem.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Du kannst die Warnung aktivieren...

-Wsign-conversion

...deaktivieren...

-Wno-sign-conversion

...einen Fehler draus machen...

-Werror=sign-conversion

...oder keinen Fehler draus machen, obwohl alle anderen Warnungen 
Fehlerstatus haben:

-Wsign-conversion -Werror -Wno-error=sign-conversion

von Yalu X. (yalu) (Moderator)


Lesenswert?

Johann L. schrieb:
> -Werror=sign-conversion

> -Wno-error=sign-conversion

Ah, diese beiden (also -W[no-]error mit einer spezifischen Warnmeldung)
waren mir auch neu. Meinen Dank auch dir.

Ich glaube, ich muss demnächst mal mein Standard-Makefile auf optimierte
Warn-/Fehlermeldungen hin anpassen :)

von Rolf M. (rmagnus)


Lesenswert?

Wobei man nochmal zwischen -Wconversion und -Wsign-conversion 
unterscheiden muß. Ersteres beinhaltet letzteres, macht aber wohl noch 
etwas mehr.

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.