Forum: Mikrocontroller und Digitale Elektronik Atmega328p/Arduino: uint64_t shl > 16 Bit geht nicht


von egon (Gast)


Lesenswert?

Wie kann ich denn die Bits eines uint64_t > 15 setzen?

Alles über Bit 15 wird ignoriert:
1
uint64_t a =1;
2
  
3
  a |= (1 << 1);   //wird ignoriert
4
  a |= (1 << 14);  //das wird gesetzt
5
  a |= (1 << 15);  //das wird gesetzt
6
  a |= (1 << 16);  //das nicht
7
  a |= (1 << 31);  //das nicht
8
  for (int i = 63; i >= 0; i--) {
9
    if ( (a & (1<<i)) > 0) {
10
      Serial.print("1");
11
    }
12
    else {
13
      Serial.print("0");
14
    }
15
    if (i%4 == 0 ) {
16
      Serial.print(" ");
17
    }
18
  }

Ich habe auch schon
1
a|= ( (uint64_t)1 << 44);
probiert, geht auch nicht.

von egon (Gast)


Lesenswert?

1
a |= (1 << 1);   //wird ignoriert
Wird nat. nicht ignoriert.

von Falk B. (falk)


Lesenswert?

@egon (Gast)

>Wie kann ich denn die Bits eines uint64_t > 15 setzen?

Indem man es richtig macht (tm).

>Alles über Bit 15 wird ignoriert:
1
a |= (1LL << 16);

Das Problem heißt Integer Promotion.

von holger (Gast)


Lesenswert?

>Ich habe auch schon
>
>a|= ( (uint64_t)1 << 44);
>
>probiert, geht auch nicht.

Wenn deine Ausgabe nicht richtig funktioniert kannst du das
gar nicht kontrollieren ob das geht oder nicht.

Hier solltest du mal ansetzen:

    if ( (a & ((uint64_t)1<<i)) > 0) {

von egon (Gast)


Lesenswert?

Falk Brunner schrieb:
> @egon (Gast)
>
>>Wie kann ich denn die Bits eines uint64_t > 15 setzen?
> Indem man es richtig macht (tm).
>>Alles über Bit 15 wird ignoriert:
> a |= (1LL << 16);
> Das Problem heißt Integer Promotion.
Das ist exakt das selbe wie (uint64_t)1 << 16.... was ich schon 
probierte.

Das Problem war das noch in der Ausgabe zu berücksichtigen, wie holger 
schrieb. Jetzt geht es auch mit der Prefixtypkonversion, diese 
Schreibweise ist mir lieber weil auffälliger.

von Karl H. (kbuchegg)


Lesenswert?

egon schrieb:

> Das Problem war das noch in der Ausgabe zu berücksichtigen, wie holger
> schrieb. Jetzt geht es auch mit der Prefixtypkonversion, diese
> Schreibweise ist mir lieber weil auffälliger.


Noch lieber sollte dir sein
1
  uint64t mask = 0x80000000;
2
3
  for (uint8_t i = 0; i < 64; i++) {
4
    if ( a & mask ) {
5
      Serial.print("1");
6
    }
7
    else {
8
      Serial.print("0");
9
    }
10
    if (i%4 == 0 ) {
11
      Serial.print(" ");
12
    }
13
    mask >>= 1;
14
  }

die Operation
1
    a << b
willst du mit einem variablen b auf einem AVR nicht haben, wenn du sie 
vermeiden kannst. Die artet für den AVR nämlich in Schwerarbeit aus.

Noch besser wäre ein Schema, bei dem du dir Funktionen baust, die 
aufeinander aufbauen, und letzten Endes einen uint64_t in Form von 8 
Bytes ausgeben.
1
void binaryNibble( uint8_t nibble )
2
{
3
  if( nibble & 0x08 ) Serial.print("1"); else Serial.print("0");
4
  if( nibble & 0x04 ) Serial.print("1"); else Serial.print("0");
5
  if( nibble & 0x02 ) Serial.print("1"); else Serial.print("0");
6
  if( nibble & 0x01 ) Serial.print("1"); else Serial.print("0");
7
}
8
9
void binaryByte( uint8_t byte )
10
{
11
  binaryNibble( byte >> 4 );
12
  Serial.print(" ");
13
  binaryNibble( byte );
14
}
15
16
void binaryWord( uint16_t word )
17
{
18
  binaryByte( word >> 8 );
19
  Serial.print( " " );
20
  binaryByte( word );
21
}
22
23
void binaryDWord( uint32_t dWord )
24
{
25
  binaryWord( dWord >> 16 );
26
  Serial.print( " " );
27
  binaryWord( dWord );
28
}
29
30
void binaryQWord( uint64_t qWord )
31
{
32
  binaryDWord( qQWord >> 32 );
33
  Serial.print( " " );
34
  binaryDWord( qWord );
35
}

so entsteht automatisch ein Satz von Funktionen, der für alle unsigned 
int Datentypen die richtige Funktion bereit hält und zur Laufzeit mit 
wenigen Schiebeoperationen auskommt, die dann auch noch alle vom 
Compiler wegoptimiert werden können, indem er einfach immer nur den 
relevanten 'Auszug' aus den Werten an die tiefer liegende Funktion 
weitergibt.
(Die binaryNibble könnte man noch eleganter schreiben, ich belass es 
aber erst mal bei dieser Version)

von egon (Gast)


Lesenswert?

Karl Heinz schrieb:

> (Die binaryNibble könnte man noch eleganter schreiben, ich belass es
> aber erst mal bei dieser Version)
Aha interessant, dachte mir schon dass 64Bit-Typen auf so einen kleinen 
Ding nicht 'echt' vorhanden sind und das durch Compiler"magie" 
hingebogen wird.

Macht man das dann auch so wenn man beliebig lange Typen haben will, 
z.B. 1024 Bit und darauf herumshiften will? Nimmt man dann ein entspr. 
langes uint8_t array und implementiert entspechende shl(), shr() die 
unter der Haube die "Drecksarbeit" machen?

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.