Atmega328p/Arduino: uint64_t shl > 16 Bit geht nicht

Gast #3679886
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.
Gast #3679895
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) {
Gast #3679902
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.
#3680359
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)
Gast #3681538
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?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren