www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik C Syntax Problem >>


Autor: saxosun (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, ich habe mal eine Frage,
was ist der Unterschied zwischen:

value >> 1;
val += value;


und

val += value >>1;

Das erste funktioniert bei mir nicht, dass zweite sehr wohl. Ich 
verstehe nur nicht, warum das so ist.

grüße
Michael

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
saxosun schrieb:
> Hallo, ich habe mal eine Frage,
> was ist der Unterschied zwischen:
>
> value >> 1;
> val += value;
>
>
> und
>
> val += value >>1;
>
> Das erste funktioniert bei mir nicht, dass zweite sehr wohl. Ich
> verstehe nur nicht, warum das so ist.

Bei erstem wird val um den Inhalt von value erhöht.
Bei zweitem wird value vorher auch noch um 1 Stelle nach rechts 
verschoben.

Autor: Stephan M. (stephanm)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Das erste funktioniert bei mir nicht, dass zweite sehr wohl.

Was soll denn der Code machen?

> value >> 1;

Sollte vom Compiler in ein "nop" übersetzt werden.

> val += value;

val = val + value;

> und val += value >>1;

val = val + (value >> 1);

Und jetzt?

Stephan

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Machs so, dann kommt das Gleiche raus:
value = value >> 1;
val += value;

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nicht ganz...

x >> 1

x wird halbiert und nicht verdoppelt.



val += value >>1;

=> Es die Hälfte von value in val addiert.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
... Mist, den Verb vergessen ...

val += value >>1;

=> Es wird die Hälfte von value in val addiert.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> => Es wird die Hälfte von value in val addiert.
Und wenn value nun signed ist?
Dann klappt das mit dem Halbieren nicht.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gast schrieb:
>> => Es wird die Hälfte von value in val addiert.
> Und wenn value nun signed ist?
> Dann klappt das mit dem Halbieren nicht.

Offiziell überlässt der C-Standard das Verhalten dann der 
Implementierung. Und die verwenden meistens anstelle eines logischen 
Shifts in so einem Fall dann einen arithmetischen Shift und dann stimmts 
wieder (bei Verwendung des 2-er Komplements, welches ebenfalls vom 
C-Standard nicht gefordert wird)

Aber wenn der Zweck der Übung tatsächlich eine Halbierung sein sollte, 
dann ist es sicherlich besser

    value = value / 2;

zu schreiben. Ob es sinnvoll ist, diese Operation durch einen 
Shift-Operation zu implementieren überlässt man am besten dem Compiler.

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die Antworten.

Das Problem war wohl einfach, dass der Compiler aus

value >> 1;

ein nop macht. ich dachte, dass

value >> 1;    genau das selbe wie     value = value >> 1; ist.

Komisch finde ich nur, dass der Compiler bei:

val += value >>1; das teilen/shiften akzeptiert. (Hat über zwei Stunden 
gedauert, bis ich das geschnallt hatte.)

grüße Michael

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael schrieb:
> ...
> ein nop macht. ich dachte, dass
>
> value >> 1;    genau das selbe wie     value = value >> 1; ist.
> ...

nein, das wäre value >>= 1;

Autor: Christian H. (netzwanze) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Haken an der Sache ist, dass "value >> 1" den Wert "value" nicht 
verändert. Das Ergebnis der Operation wird nicht verwendet. Die ganze 
Zeile wird wegoptimiert (und nicht durch ein NOP ersetzt).

Bei "val += value >> 1" wird das Ergebnis von "value >> 1" sehr wohl 
verwendet - und zwar zum Wert in "val" dazuaddiert.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:

> zu schreiben. Ob es sinnvoll ist, diese Operation durch einen
> Shift-Operation zu implementieren überlässt man am besten dem Compiler.

Nicht zuletzt, weil auch bei Zweierkomplement und entsprechenden Shifts
   x >> n
und
   x / (1<<n)
durchaus verschiedene Ergebnisse erbringen können. Nämlich dann wenn's 
negativ wird. Der Shift rundet anders als die Division.

Autor: Tim Seidel (maxxie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Komisch ist das nicht.

value >> 1 ;

Shiftet ebenfalls nur wird das Ergebnis nicht verwendet und so bereits 
ohne Optimierung einfach weggelassen. In der CMa würde in etwa
loada value
load 1
shiftr
pop
generiert werden. Also der Wert von value und 1 in den Stack geladen. 
Der Shift konsumiert beide und legt das Ergebnis des Shifts auf den 
Stack ab. anschliessend (die Übersetzung des ;) wird ein Wert auf dem 
Stack konsumiert.

Benutzt du value >> 1 in einer Zuweisung (result = value >> 1), dann 
ändert sich etwas:
loada value
load 1
shiftr
storea result
pop
Bevor der Stack nach dem Ausdruck aufgeräumt wird, wird er gespeichert. 
Aber auch hier bleibt der Inhalt von value unverändert.

val += value >>1;
Erzeugt in etwa
loada val
loada value
load 1
shiftr
add
storea val
pop
Es bleibt auch hier value unverändert. Das Zwischenergebnis des Shift 
wird auf dem CMa-Stack aber sofort gemeinsam mit der Inhalt von val 
konsumiert und die Summe auf dem Stack abgelegt, die dann in val 
zurückgespeichert wird.
Anschliessend wird auch hier der CMa Stack wieder durch das ";" 
aufgeräumt.

Autor: Juergen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Und wenn value nun signed ist?
> Dann klappt das mit dem Halbieren nicht.

Doch, nur dass dann sowohl der Originalwert als auch das Ergebnis 
negativ sein koennen. Genau deshalb wird bei signed das oberste Bit 
geklont anstatt es auf null zu setzen.

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.