mikrocontroller.net

Forum: Compiler & IDEs wie geht der Compiler mit folgendem Ausdruck um?


Autor: technikus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe ein Verständnisproblem und bitte daher um eure Hilfe.

Es geht um folgende Codezeile:
phase.value16=phase.value16+DEGREE_180-(2*(phase.value16-DEGREE_90));

phase.value16 ist ein unsigned int 16 aus einer union. Das 
Gesamtergebnis der Formel ist immer positiv.
Doch wie geht der Compiler mit
(2*(phase.value16-DEGREE_90))

um, wenn das Ergebnis in der Klammer negativ ist? Anders gefragt, kann 
das Ergebnis negativ sein wenn mit unsigned Variablen gearbeitet wird?

Z.B.

#define DEGREE_90   512
#define DEGREE_180  1024
phase.value16=0;

(2*(phase.value16-DEGREE_90))


ist das Ergebis der Klammer dann -1024 ?

Also das Gesamtergebnis
phase.value16 = 0 + DEGREE_180-(2*(phase.value16-DEGREE_90));

phase.value16 == 0 ???


Ich hoffe das ich mich einigermaßen verständlich ausgedrückt habe.

Gruß
Ernst

AVR GCC mit AVR Studio

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
technikus schrieb:

> Anders gefragt, kann
> das Ergebnis negativ sein wenn mit unsigned Variablen gearbeitet wird?

Nein.

> #define DEGREE_90   512
> #define DEGREE_180  1024
> phase.value16=0;
> 
> (2*(phase.value16-DEGREE_90))
> 
>
> ist das Ergebis der Klammer dann -1024 ?

Nein, 64512.

> Also das Gesamtergebnis
>
> phase.value16 = 0 + DEGREE_180-(2*(phase.value16-DEGREE_90));
>
> phase.value16 == 0 ???

Nein, 2048.
Aber auch bei -1024 in der Klammer wäre das Ergebnis doch 2048. Wie 
kommst du auf 0?

Autor: Zabriskie (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vorsicht mit implizitem Typecasting! Es kann sein, dass der compiler das 
DEGREE_90 als erstes als signed int liest und dann für die Variable ein 
implizites Typecasting auf signed durchführt.

Deshalb am besten in solchen Fällen im Zweifelsfall immer sowas wie

(2*(phase.value16-(unsigned int)DEGREE_90))

schreiben. Bin mir gerade nicht sicher, was er mit einer negativen Zahl 
als Zuweisung macht. Könnte mir vorstellen, das das einen Überlauf gibt 
oder vielleicht NaN, wenn das wie bei Floating Point vorgesehen ist, 
aber keine Ahnung.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zabriskie schrieb:
> Es kann sein, dass der compiler das DEGREE_90 als erstes als signed int
> liest

Was heißt hier "kann sein"? DEGREE_90 ist ein signed int.

> und dann für die Variable ein
> implizites Typecasting auf signed durchführt.

Nö, unsigned "gewinnt".

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Anders ausgedrückt:  unsigned ist der "höhere" Typ; eine implizite 
Konversion von unsigned int nach int kann NIE stattfinden.

Autor: Zabriskie (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Im Prinzip (und praktisch) habt Ihr Recht, aber

Stefan Ernst schrieb:
> Zabriskie schrieb:
>> Es kann sein, dass der compiler das DEGREE_90 als erstes als signed int
>> liest
>
> Was heißt hier "kann sein"? DEGREE_90 ist ein signed int.

<Klugscheißermodus>
Nö :). Da würde ich gerne mal den C Standard zu sehen.

unsuffixed decimal   int, long int, C only long long int

http://publib.boulder.ibm.com/infocenter/comphelp/...

Der Typ von numerischen literals hängt demnach von der Interpretation 
der Umgebung durch den Compiler ab (Ok unsigned int ist es nicht). Ich 
erwähne das nur, weil ich schonmal über den Unterschied zwischen "5." 
und "5" gestolpert bin.

</Klugscheißermodus>

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zabriskie schrieb:

> Da würde ich gerne mal den C Standard zu sehen.
The type of an integer constant is the first of the corresponding list
in which its value can be represented.

Suffix | Decimal Constant | Octal or Hexadecimal Constant
------+------------------+------------------------------
none  | int              | int
      | long int         | unsigned int
      | long long int    | long int
      |                  | unsigned long int
      |                  | long long int
      |                  | unsigned long long int
------+------------------+------------------------------
Ergo ist es ein int (was identisch zu signed int ist).

> Der Typ von numerischen literals hängt demnach von der Interpretation
> der Umgebung durch den Compiler ab (Ok unsigned int ist es nicht).

Der Standard ist da eindeutig, da gibt es keinen 
Interpretationsspielraum.

> Ich erwähne das nur, weil ich schonmal über den Unterschied zwischen
> "5." und "5" gestolpert bin.

Das ist ja nun wieder eine ganz andere "Baustelle".

Autor: technikus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan Ernst schrieb:
> Nein, 2048.
> Aber auch bei -1024 in der Klammer wäre das Ergebnis doch 2048. Wie
> kommst du auf 0?

Fehler - ich meinte 2048

Vielen Dank für die aufschlussreichen Antworten

Gruß
Ernst

Autor: Zabriskie (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
technikus schrieb:
> Vielen Dank für die aufschlussreichen Antworten

Ebenfalls Danke für die Richtigstellung Stefan. Demnach muss man sich 
erst ab 32768 Sorgen machen (bei einer garantierten Länge von int von 16 
bit).

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.