Bitabgleich vereinfachen

Hallo in die Runde.

Habe mir hier einen Bitabgleich für programmiert. Da die If Abfrage bei mehr features recht lang werden kann (speziell bei "OFF"), gibt es da noch bessere einfachere Parse-Möglichkeiten/Lösungen?

void setup() {
  // put your setup code here, to run once:
  //Initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  Serial.println();
  Serial.println("Start");

  uint8_t setting       = 0b00100010;

  uint8_t feature_front = 0b00000011;
  uint8_t feature_back  = 0b00111100;

  Serial.print("Park");
  if ((setting & feature_front) == feature_front) Serial.print(":FRONT");
  if ((setting & feature_back) == feature_back) Serial.print(":BACK");
  if ((setting & feature_front) != feature_front && (setting & feature_back) != feature_back) Serial.print(":OFF");

  Serial.println();
  Serial.println("Done");
}

void loop() {
  // put your main code here, to run repeatedly:

}

harryberlin: gibt es da noch bessere einfachere Parse-Möglichkeiten/Lösungen?

Bis auf die Tatsache, dass ich horizontale Scrollerei blöd finde, sehe ich kein wesentliches Potential für Codeverbesserung.

Wenn Du Extrem-Code-Tuner-Ultraplus werden möchtest, erzeugst Du am besten den Assemblercode und analysierst diesen.

Gruß

Gregor

PS: Denk dran: Der größte Vorteil von C bzw. C++ ist, dass sehr hardwarenah programmiert werden kann. Zudem sind die Compiler mittlerweile sehr gut, wenn es um Optimierungen geht.

Zuerst mal kommt es darauf an, was Du unter dem verstehst, das Du "Bitabgleich" nennst.

Zur Behandlung von Multi-Bit Feldern schau mal in der C/C++ Doku nach "bitfield". Solche bitfields werden z.B. verwendet, um die Bits in der Hardware des Controllers zu benennen.

Ich möchte Werte in den EEPROM speichern und anhand dessen ein Text ausgeben.

Im Grunde gehts mir um die Schreibweise des Codes, um es überschaubar zu halten.

Hab mir jetzt ne Hilfsfunktion gebaut:

bool get_feature(uint8_t setting, uint8_t feature) {
  return (setting & feature) == feature;
}

harryberlin: Im Grunde gehts mir um die Schreibweise des Codes, um es überschaubar zu halten.

Dann solltest Du IMO vor allen Dingen weniger auf „sachlich optimalen“ Code sondern mehr auf die „Optik“ achten. Also Dinge so „formatieren“, dass sie leicht les- und nachvollziehbar sind - passende Einrückungen, einheitliche Klammerungen usw.

Was „leicht lesbar“ heißt, hängt allerdings auch stark davon ab, wer's liest :-)))

Gruß

Gregor

PS: Nur mal ein Schnipselchen aus einem sehr alten Programm. Mir war und ist ziemlich egal, ob der Compiler den schnellstmöglichen Code erzeugt. Wichtiger war mir, auch in ein paar Jahren noch leicht erkennen zu können, worum's geht: /

/ Bildbereich fuellen (Flood-Fill-Algorithmus)
//    Funktionsweise:
//      - RGBA-Werte des (Start-)Pixels als Referenzfarbe sichern
//      - (Start-)Pixel auf die neue Farbe setzen
//      - gucken, ob eines der Nachbarpixel
//        links, oben, rechts oder unten
//        die Referenzfarbe hat. Wenn ja: -> Rekurs mit neuen Koordinaten
bool gImage::floodFill(gImage& _tp, int _x, int _y, gColor _color)
{  
  // Aktuelle RGBA-Werte des Pixels sichern
  gColor tmp(
             _tp.getPixelR(_x, _y),
             _tp.getPixelG(_x, _y),
             _tp.getPixelB(_x, _y),
             _tp.getPixelA(_x, _y)
         );

  if (
      (_color.getA()==0) || (
                              ((_color.getR()==tmp.getR()) && 
                   (_color.getG()==tmp.getG()) &&
                   (_color.getB()==tmp.getB()) &&
                   (_color.getA()==tmp.getA()))
                              &&
                  (_color.getR()+
                               _color.getG()+
                               _color.getB()+
                               _color.getA()==0)
                 )
     )
    { return(false); }

  // Neue Farbe setzen
  _tp.setPixel(_x, _y, _color);

  // Pixel links testen
  if (_tp.getPixelR(_x-1, _y)==tmp.getR() &&
      _tp.getPixelG(_x-1, _y)==tmp.getG() &&
      _tp.getPixelB(_x-1, _y)==tmp.getB() &&
      _tp.getPixelA(_x-1, _y)==tmp.getA() )
  {
    floodFill(_tp, _x-1, _y, _color);
  }
  // Pixel oben testen
  if (_tp.getPixelR(_x, _y-1)==tmp.getR() &&
      _tp.getPixelG(_x, _y-1)==tmp.getG() &&
      _tp.getPixelB(_x, _y-1)==tmp.getB() &&
      _tp.getPixelA(_x, _y-1)==tmp.getA() )
  {
    floodFill(_tp, _x, _y-1, _color);
  }
  // Pixel rechts testen
  if (_tp.getPixelR(_x+1, _y)==tmp.getR() &&
      _tp.getPixelG(_x+1, _y)==tmp.getG() &&
      _tp.getPixelB(_x+1, _y)==tmp.getB() &&
      _tp.getPixelA(_x+1, _y)==tmp.getA() )
  {
    floodFill(_tp, _x+1, _y, _color);
  }
  // Pixel unten testen
  if (_tp.getPixelR(_x, _y+1)==tmp.getR() &&
      _tp.getPixelG(_x, _y+1)==tmp.getG() &&
      _tp.getPixelB(_x, _y+1)==tmp.getB() &&
      _tp.getPixelA(_x, _y+1)==tmp.getA() )
  {
    floodFill(_tp, _x, _y+1, _color);
  }
  return(true);
}

DrDiettrich: Zur Behandlung von Multi-Bit Feldern schau mal in der C/C++ Doku nach "bitfield". Solche bitfields werden z.B. verwendet, um die Bits in der Hardware des Controllers zu benennen.

Das sind keine Bitfelder. Die Bit-Namen sind nur deren Nummern. Dann muss man sich durch Schieben einer 1 nach links die Bitmaske selbst erzeugen und den Wert durch Verunden Auslesen. Also in etwa was hier auch gemacht wird

Serenifly: Das sind keine Bitfelder.

Das was? Bitfields gehören seit K&R zu C und können auch in Verbindung mit µC benutzt werden, um Code zu verschönern.

Klar kann man das machen. Das hat sich aber so angehört als dass du gesagt hast, dass wäre bei den AVR Registern so. Aber das ist hier nicht der Fall

Ich weiß nicht wo "hier" ist. Mir sind Bitfields in den letzen Wochen im Forum oder in Bibliotheken begegnet, deshalb kam ich bei dieser Anfrage drauf.

Hallo,

stellt setting die frischen Daten dar und die feature... sind konstante Bitmasken zum Vergleichen?