mikrocontroller.net

Forum: Compiler & IDEs Shift bei uint32_t nur bis 16 Stellen?


Autor: Stefan B. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Irgendwie habe ich ein Problem in einer Funktion bei mir und komme nicht 
auf den Fehler.

Ich habe eine Variable "data" vom Typ uint32_t und will mir von dieser 
das Bit an der Stelle "index" zurückgeben lassen.

Dafür habe ich mir folgende Funktion geschrieben:
uint8_t get_bit(uint32_t data, uint8_t index)
{
    // index may not be higher than 31 for 32 bit value
    if(index > 31)
        return 0;
    
    // extract the n-th bit by and-ing "data" with just one binary "1" in n-th bit
    // then the result is shifted right by n places to get the bit we want
    return (uint8_t)((uint32_t)(data & (uint32_t)(1 << index)) >> index);
}

Das funktioniert aber nur bis zum 16. Bit, danach kommt immer "0" 
zurück.

Warum ist das so, hab ich irgendwas übersehen?
Oder kann man das eleganter/schneller realisieren?

Das komplette Programm ist im Anhang.
Verwendet wird AVR Studio 4.18, µC ist ein ATtiny45.

Für Tipps wäre ich sehr dankbar, ich weiß echt nicht mehr weiter...

MfG Stefan

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
return (uint8_t)((uint32_t)(data & (uint32_t)((uint32_t)1 << index)) >> 
index);

Autor: Robert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
return (uint8_t)((data & (1L << 31)) >> index);

Autor: Robert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
besser noch:
return (data & (1L << index))?1:0;

Das spart das zurückshiften.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
return (data >> index) & 1;

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zur Erklärung:

"1 << index" ist vom Typ int, da 1 vom Typ int ist. Dieser Typ ist auf 
dem AVR aber nur 16 Bit groß. Die ganze Casterei danach ändert daran 
nichts mehr.

Es sei noch angemerkt, daß die Funktion in manchen Fällen den Code 
deutlich langsamer machen kann.

Nur der Vollständigkeit halber, hier noch eine Variante: ;-)
return !!(data & (1UL << index));

Autor: Stefan B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke an alle, das wars!

Ist ja auch logisch dass "1" ein int und kein long ist, war wohl gestern 
schon zu spät für mich...
Und im Debugger konnte ich es mir auch nicht anzeigen lassen, 
anscheinend wurde meine extra dafür angelegte Variable wieder 
wegoptimiert.

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.