www.mikrocontroller.net

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


Autor: Askan Simon (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

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

das gleiche wie
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

Autor: Skua (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jo

Autor: Μαtthias W. (matthias) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

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

Matthias

Autor: micha (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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"

Autor: micha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

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

Bewertung
0 lesenswert
nicht 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
int main()
{
  unsigned int i = 28;
  unsigned int j = 34;
  unsigned int Mittelwert;

  Mittelwert = ( i + j ) >> 1;
}

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.

Autor: Askan Simon (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

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

Viele Grüße
Askan

Autor: oha (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

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

Bewertung
0 lesenswert
nicht 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

Autor: oha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In der Tat. Ist es nicht.

Autor: Martin (Gast)
Datum:

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

Wart = Wert div 2

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

Bewertung
0 lesenswert
nicht 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
void swap( int* a, int* b )
{
  *a ^= *b;
  *b ^= *a;
  *a ^= *b;
}

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
int main()
{
  int i = 5;

  swap( &i, &i );
}

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)

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.