Forum: Mikrocontroller und Digitale Elektronik Kleine NewBee Frage - Rechenoperation ">>=1" gleich "/2"?


von Askan Simon (Gast)


Lesenswert?

Hallo,

eine ganz kleine Verständnisfrage
ist
1
Zahl >>= 1;

das gleiche wie
1
Zahl = Zahl / 2;

Sorry, aber in meinem AVR Buch finde ich hierzu nichts und
es läßt sich mit google so schlecht nach der Zeichenkette
">>=" suchen.

Danke & Viele Grüße
Askan

von Skua (Gast)


Lesenswert?

Jo

von Μαtthias W. (matthias) Benutzerseite


Lesenswert?

Hi

bei vorzeichenlosen (unsigned) Zahlen ist das so. Ja.

Matthias

von micha (Gast)


Lesenswert?

IMHO gibt es die kurzschreibweise ">>=" analog zu "+=" nicht.
Wenn dann "zahl = zahl >> 1". Das ist eine Bit-Verschiebung um eine 
Stelle nach rechts und (für Integers) entspricht dies einer Division 
durch 2. Google-Stichwort "shift operator"

von micha (Gast)


Lesenswert?


von Karl H. (kbuchegg)


Lesenswert?

Aber bitte, bitte, bitte, lass die Finger davon.

Dein Compiler weiß ganz genau, wenn er eine Division durch 2 durch ein 
einmaliges Schieben ersetzen kann.

Mit
1
int main()
2
{
3
  unsigned int i = 28;
4
  unsigned int j = 34;
5
  unsigned int Mittelwert;
6
7
  Mittelwert = ( i + j ) >> 1;
8
}

dokumentierst du keineswegs, dass du ein unglaublich guter Hacker bist, 
sondern eher dass du so dämlich bist, zu glauben dass deine 
Compilerbauer Vollidioten sind.

Spätestens wenn du irgendwann mal gezwungen bist, den Datentyp der 
beteiligten Variablen zu ändern, fällt dir das nämlich auf den Kopf.
(Siehe zb. diesen Thread hier)
Beitrag "Re: Doku für Warning / Error messages?"

Benutz das Bit-Schieben nur dann, wenn du tatsächlich Bits schieben 
willst. Wenn du, logisch gesehen, dividieren willst, dann schreib das 
auch so hin.

von Askan Simon (Gast)


Lesenswert?

Hallo,

vielen Dank! werde natürlich dann "/" benutzen. :)

Viele Grüße
Askan

von oha (Gast)


Lesenswert?

Ueberschaetze nie den Compilerbauer. Ich hab einen Compiler der erwartet 
bei einer Division in der Regel Float typen. Mit einer Schiebe operation 
zeigt man dem Compiler, dass man auch mit einem Integer Resultat 
zufrieden ist.

von Karl H. (kbuchegg)


Lesenswert?

oha wrote:
> Ueberschaetze nie den Compilerbauer. Ich hab einen Compiler der erwartet
> bei einer Division in der Regel Float typen. Mit einer Schiebe operation
> zeigt man dem Compiler, dass man auch mit einem Integer Resultat
> zufrieden ist.

Das kann dann aber kein C Compiler sein.
Das wiederspricht jeglicher C-Sprachdefinition

von oha (Gast)


Lesenswert?

In der Tat. Ist es nicht.

von Martin (Gast)


Lesenswert?

War es nicht in C auch so wie in Pascal, das man sowas schreiben kann 
???

Wart = Wert div 2

von Karl H. (kbuchegg)


Lesenswert?

Martin wrote:
> War es nicht in C auch so wie in Pascal, das man sowas schreiben kann
> ???
>
> Wart = Wert div 2

Nein.
In der Beziehung sind die Regeln in C durchgängig und einfach.
Um zu entscheiden, wie eine Operation durchgeführt wird (als Fliesskomma 
oder als Ganzzahlarithmetik) werden ausschliesslich die an der Operation 
beteiligten Operanden herangezogen. Deren Datentyp entscheidet, wobei in 
einem Schritt zuvor die Datentypen erst mal auf gleich gezogen werden.

In C schreibst du immer / und je nachdem welche Datentypen links und 
rechts davon stehen, sucht sich der Compiler die passende Division raus.

Davon unabhängig sind dann weiterführende Optimierungsmöglichkeiten, die 
sich daraus ergeben ( Multiplikation mit kleinen Zahlen kann oft durch 
eine Schiebe/Additionssequenz ersetzt werden, Division durch 2-er 
Potenzen durch eine Schiebeoperation, ... ). Der Programmierer soll sich 
im Idealfall nicht um derartige Optimierungen kümmern, das ist der Job 
des Compilers. Auf einem 8-Bit µC kann es da natürlich ab und zu 
Ausnahmen geben, weil dessen Lieblingsdatentyp nun mal ein 8-Bit Typ 
ist, während C eigentlich int als Standarddatentyp präferiert (der auf 
einem 8-Bit µC vergleichsweise umständlich gehandhabt wird). Das ändert 
aber nichts an der generalisierten Aussage: Die meisten der sog. Hacks, 
für die C berühmt berüchtigt ist, sind heute ein Anachronismus und 
längst durch die technische Entwicklung im Bereich Compilerbau überholt.

Anderes Beispiel:
In den C-Newsgroups vergeht kaum eine Woche, in der nicht wieder irgend 
ein Schlaukopf auftaucht und meint er hätte die ultimative Lösung für 
einen Variablenswap gefunden
1
void swap( int* a, int* b )
2
{
3
  *a ^= *b;
4
  *b ^= *a;
5
  *a ^= *b;
6
}

Das 'Tolle' daran ist, dass er keine temporäre Variable braucht.
Soweit so gut. Bist du den Poster dann mal aufforderst, sich anzusehen 
was bei
1
int main()
2
{
3
  int i = 5;
4
5
  swap( &i, &i );
6
}

rauskommt.
Wenn du Variablen sicher und zuverlässig in allen Fällen swappen willst, 
dann kommst du um eine temporäre Variable nicht herum. Nur weil du eine 
temporäre Variable hast, heist das ja noch lange nicht, dass im fertigen 
Programm diese Variable auch auftauchen wird. So eine temporäre Variable 
kann ja auch ein freies CPU-Register sein, bzw. viele CPU's haben eine 
Register-Swap Operation. Der Compiler kennt das alles und benutzt es 
auch dementsprechend. Das einzige was man mit solch 'cleveren' Hacks im 
schlimmsten Fall erreicht, ist das der Compiler die Absicht nicht mehr 
erkennen kann und eine entsprechende Optimierung nicht mehr einbaut. Und 
dann geht der Schuss ganz schnell nach hinten los.
Selbiges mit dem Schlüsselwort 'register'. Überlass dem Compiler, welche 
Variablen er wann in welchen Registern hält. Der kann das viel besser 
entscheiden, denn er macht keine Aus-dem-Bauch Entscheidung, sondern 
eine Datenflussanalyse um sich die Situation anzusehen. (Und die meisten 
Compiler ignorieren genau aus diesem Grund register heutzutage sowieso)

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.