Wie kann ich 4 Byte Werte in eine int32 Variable speichern?

OP #5242037
Lesenswert?

Hallo,

ich habe folgendes Problem:

Aus einem Byte Array lese ich 4 Bytes aus (beginnend mit MSB) und möchte 
die Werte in eine uint32 Variable wie folgt speichern:
1
  baselineNewHighByte  = ( (baseline[0]<<8) + (baseline[1]) );
2
  baselineNewLowByte  = ( (baseline[3]<<8) + (baseline[4]) );
3
  baselineNew      = ( (baselineNewHighByte<<8) + (baselineNewLowByte) );

baseline[0] = 0x8f
baseline[1] = 0x40
baseline[3] = 0x8f
baseline[4] = 0x16

Für baselineNew erhalte ich aber 0x0000cf16
baselineNewHighByte und baselineNewLowByte sind uint16 Variablen. Die 
hier gespeicherten Werte mit 0x8f40 und 0x8f16 stimmen.

Muss ich für uint32 Variablen eine andere Vorgehensweise wählen?
Gast #5242060
Lesenswert?

Sowas..?
1
union{
2
  uint8_t auc[4];
3
  uint32_t ul;
4
} unVariable;
5

6
uint8_t aucAnderevariable[4] = {0x12, 0x34, 0x56, 0x78};
7

8
unVariable.auc[0] = aucAnderevariable[0];
9
unVariable.auc[1] = aucAnderevariable[1];
10
unVariable.auc[2] = aucAnderevariable[2];
11
unVariable.auc[3] = aucAnderevariable[3];
12

13
if(unVariable.ul == 0x12345678){
14
  //HOORAY!
15
}
#5242065
Lesenswert?

@M. G. (ixil96)

>Aus einem Byte Array lese ich 4 Bytes aus (beginnend mit MSB) und möchte
>die Werte in eine uint32 Variable wie folgt speichern:
>  baselineNewHighByte  = ( (baseline[0]<<8) + (baseline[1]) );
>  baselineNewLowByte  = ( (baseline[3]<<8) + (baseline[4]) );
>  baselineNew      = ( (baselineNewHighByte<<8) + (baselineNewLowByte) );

Da fehlt ein Cast. Eher so.
1
  baselineNew      = (long)baseline[0] << 0 |
2
                     (long)baseline[1] << 8 |
3
                     (long)baseline[2] << 16 |
4
                     (long)baseline[3] << 24;

>baselineNewHighByte und baselineNewLowByte sind uint16 Variablen.

Das ist das Problem. Der Compiler rechnet bei diesen Schiebeoperationen 
nur mit 16 Bit, wodurch man niemals Daten in höhere Bits schieben kann. 
Mit dem Cast rechnet er mit 32 Bit.
Moderator (Firma: Titel) Persönliche Seite #5242075
Lesenswert?

M. G. schrieb:
> Muss ich für uint32 Variablen eine andere Vorgehensweise wählen?
Nicht bei einem PC, denn dort ist der Integer 32 Bit breit.

Wenn du bei deinem unbekannten Compiler aber einen 16 Bit Integer hast, 
dann musst du ihm bei Rechenoperationen (auch und besonders mit 
Konstanten) mitteilen, dass er sie doch in 32 Bit Breite ausführen 
solle...
#5242105
Lesenswert?

@M. G. (ixil96)

>Habs jetzt mit dem Typecast versucht
>baselineNew = ( (long)(baseline[0]<<24) | (long)(baseline[1]<<16) | 
(long)>(baseline[3]<<8) | (long)(baseline[4]) );

>aber die obersten zwei bytes sind 0xffff

Was wohl daran liegt, daß long vorzeichenbehaftet ist. Und wenn der 
Compiler eine 16 Bit Zahl auf 32 Bit vorzeichenrichtig erweitert, 
kopiert er Bit 15 in alle Bits 16-31.
#5242107
Lesenswert?

M. G. schrieb:
> Habs jetzt mit dem Typecast versucht
> baselineNew = ( (long)(baseline[0]<<24) | (long)(baseline[1]<<16) |
> (long)(baseline[3]<<8) | (long)(baseline[4]) );
>
> aber die obersten zwei bytes sind 0xffff

Du muss bei Index 0 beginnen:
1
/* Generiert aus vier Byte Werten ein uint32_t */
2
static inline uint32_t u8u32(uint8_t *src)
3
{
4
   return ((src[3] << 24) | (src[2] << 16) | (src[1] << 8) | (src[0]));
5
}

Hier meine Lösung die ich verwende.

edit:

Über den Namen der Fkt. kann man sich streiten...
Kannst es dann so verwenden:
1
uint8_t buf[4];
2
uint32_t value;
3

4
// buf mit Werten befüllen
5

6
value = u8u32(&buf[0]);
Gast #5242127
Lesenswert?

Falk B. schrieb:
> baselineNew      = (long)baseline[0] << 0 |
>                      (long)baseline[1] << 8 |
>                      (long)baseline[2] << 16 |
>                      (long)baseline[3] << 24;

Umgekehrte Reihenfolge.
Das MSByte steht wohl in baseline[0].
Siehe:

M. G. schrieb:
> Aus einem Byte Array lese ich 4 Bytes aus (beginnend mit MSB) und möchte
> die Werte in eine uint32 Variable wie folgt speichern:
>   baselineNewHighByte  = ( (baseline[0]<<8) + (baseline[1]) );

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