C Syntax Problem >>

#1493234
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.
#1493241
> 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
#1493290
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.
Gast #1493613
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
#1493624
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.
#1493647
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
1
loada value
2
load 1
3
shiftr
4
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:
1
loada value
2
load 1
3
shiftr
4
storea result
5
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
1
loada val
2
loada value
3
load 1
4
shiftr
5
add
6
storea val
7
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.
Gast #1493891
> 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

Eine eigene Frage? Dieser Thread ist über 16 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.