einzelne BIT setzen

Hallo,
ich habe da ein seltsames Phänomen:

Ich möchte in einer Variable mittels Schleife, einzelne BITs setzen:

int i=0;
void setup() 
{
  Serial.begin(9600);
}

void loop() 
{
  for (int n=0;n<=7;n++)
  {
    i = int(pow(2,n));
    Serial.print(n);
    Serial.print("  ");
    Serial.print(i);
    Serial.print("  ");
    Serial.println(int(i),BIN);    
    //delay(10);
  }
  
  Serial.println("");
  Serial.println("---");
  Serial.println("");
  delay(3000);
}

allerdings erhalte ich folgendes Ergebnis:

0 1 1
1 2 10
2 3 11
3 7 111
4 15 1111
5 31 11111
6 63 111111
7 127 1111111

Erwarten würde ich folgendes:
0 1 1
1 2 10
2 4 100
3 8 1000
4 16 10000
5 32 100000
6 64 1000000
7 128 10000000

Ist das ein interner Fehler oder habe ich da etwas übersehen?

Folgender Code funktioniert, ist aber nicht die Aufgabe:

unsigned int i=1;
void setup() 
{
  Serial.begin(9600);
}

void loop() 
{
  i=1;
  for (unsigned int n=0;n<=7;n++)
  {
    Serial.print(n);
    Serial.print("  ");
    Serial.print(i);
    Serial.print("  ");
    Serial.println(int(i),BIN);    
    i = i<< 1;

  }
  
  Serial.println("");
  Serial.println("---");
  Serial.println("");
  delay(3000);
}

0 1 1
1 2 10
2 4 100
3 8 1000
4 16 10000
5 32 100000
6 64 1000000
7 128 10000000


http://www.arduino.cc/en/Reference/BitSet
http://www.arduino.cc/en/Reference/BitClear
http://www.arduino.cc/en/Reference/BitWrite

Das sind Makros hierfür:

#define bitSet(value, bit) ((value) |= (1UL << (bit)))
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))

Erst schiebt man eine 1 an die entsprechende Stelle. Setzen geht mit ODER. Und löschen mit einem UND mit dem Inversen.

Danke, :slight_smile:

genauso sollte es sein.

int i=0;
int n=0;

void setup() 
{
  Serial.begin(9600);
}

void loop() 
{
  
  for (n=0; n<=11; n++)
  {
    bitSet(i, n);
    Serial.print(n);
    Serial.print("\t");
    Serial.print(i);
    Serial.print("\t");
    Serial.print(i,BIN);    
    Serial.println("");
    delay(1);
    bitClear(i, n);
  }
  
  Serial.println("");
  Serial.println("---");
  Serial.println("");
  delay(3000);
}

0 1 1
1 2 10
2 4 100
3 8 1000
4 16 10000
5 32 100000
6 64 1000000
7 128 10000000
8 256 100000000
9 512 1000000000
10 1024 10000000000
11 2048 100000000000

Wenn du Programmieranfänger bist kann ich nur raten, wenn etwas nicht funktioniert, versuch herauszufinden und zu verstehen worin genau das Problem liegt.
Sonst wirst du den selben Fehler wahrscheinlich immer und immer wieder machen.

In diesem Fall liegt das Problem darin daß du nicht berücksichtigt hast daß die pow()-Funktion als Ergebnis eine Fließkommazahl zurückgibt, und daß int() nicht rundet sondern die Nachkommastellen abschneidet. Du könntest dein ursprüngliches Programm also reparieren indem du eine Rundungsfunktion einbaust.

Die Lösung mit Bitset ist natürlich viel effizienter da sie keine komplizierten mathematischen Funktionen und Typkonvertierungen benötigt.

Fleißkommazahlen sind etwas ungenau. Sie sind auf 6 bis 7 Stellen genau aber eben nicht 100%.

2^2 müßte 4 ergeben aber in Wahrheit ergibt es etwas wie 3,99999 wei funktionen wie POW, SQR, sin, cos, tan ecc mitels Polinome berechent werden und nicht diskret. . In int gewandelt ist das dann 3 .

Daum ist das inkrementieren b zw Decrementieren einen Fleißkommazahl bei einem bestimmten Wert schluß.

Das ist nicht nur einen Arduinoeigenheit sonder auch der PC macht sowas.

Grüße Uwe