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

OP #5242037
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 #5242048
Wenn man 16 Bit Variablen schon im Namen als "byte" bezeichnet

M. G. schrieb:
> baselineNewHighByte

muss man sich nicht wundern wenn man sie nur 8 bit statt 16 schiebt:

M. G. schrieb:
> (baselineNewHighByte<<8

Leute denkt doch mal für 2 Sekunden nach wie man seine variablen 
sinnvoll benamsd.
Gast #5242054
Du musst das High Word (das Du Byte nennst) 16 statt 8 Bits shiften.

Oder gleich alles zusammen:

baselineNew = (baseline[0]<<24)
              | (baseline[1]<<16)
              | (baseline[2]<<8)
              | baseline[3];
Gast #5242060
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
@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
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...
Gast #5242100
Weiterhin:
Du solltest lernen, wie man bis 4 zählt.
Im Moment klemmt es ab 1 noch etwas....

Und wie dein Cast wirkt, solltest du noch mal im Handbuch nachlesen.
Denn so wird das nichts.
#5242105
@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
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
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

Eine eigene Frage? Dieser Thread ist über 8 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.