C Syntax Problem >>

#1493234
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.
#1493290
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.
Gast #1493613
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
#1493624
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.
#1493647
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
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
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren