Build int32_t of 4 uint8_t values

I have a function that builds values int32_tfrom 4 uint8_tand uses the following test to have some confidence that my results are what they are expected from, because I depending on (what I think) the Behavior performed.

Does it make sense what I'm doing? Are there any better ways to build int32_t?

int32_t expected = -1;
int32_t res = 0;
uint8_t b0 = 0xFF;
uint8_t b1 = 0xFF;
uint8_t b2 = 0xFF;
uint8_t b3 = 0xFF;                                                      
res |= b0;                                            
res |= b1 << 8;                                                   
res |= b2 << 16;
/* This is IDB, this value cannot be represented in int32_t */
res |= ((uint32_t) b3) << 24;                                                       
ck_assert(res == expected); 
+4
source share
4 answers
typedef union
{
    uint32_t  u32;
    int32_t   i32;
    float     f;
    uint16_t  u16[2];
    int16_t   i16[2];
    uint8_t   u8[4];
    int8_t    i8[4];
    char      c[4];
} any32;

. , 32- 8- . , I2C SPI. , 8.24 ( 16.16 24.8). #defines, :

//!\todo add 16-bit boundary endian-ness options
#if (__LITTLE_ENDIAN)
 #define FP_824_INTEGER  (3)
 #define FP_824_FRAC_HI  (2)
 #define FP_824_FRAC_MID (1)
 #define FP_824_FRAC_LOW (0)
#elif (__BIG_ENDIAN)
 #define FP_824_INTEGER  (0)
 #define FP_824_FRAC_HI  (1)
 #define FP_824_FRAC_MID (2)
 #define FP_824_FRAC_LOW (3)
#else
 #error undefined endian implementation
#endif
+2

, , uint32_t , .

, - . , :

  • - undefined. , .
  • undefined.
  • , , , ( , ).

, , , uint32_t. :

res |= (int32_t) ((uint32_t)b1 << 8;)

, .


  • Endianess , -. - ( punning, ..), .
  • . stdint.h 2 . 1 .
+3

int32_t, uint32_t uint8_t, , , , , (. C11 §6.3.1.3):

#include <stdint.h>

void foo(void)
{
    uint8_t b0 = 0xef;
    uint8_t b1 = 0xbe;
    uint8_t b2 = 0xad;
    uint8_t b3 = 0xde;
    uint32_t ures = b0 | ((uint32_t)b1 << 8) |
                    ((uint32_t)b2 << 16) | ((uint32_t)b3 << 24);
    // Avoid implementation-defined value or signal...
    int32_t sres = (ures < (uint32_t)INT32_MIN) ?
                   (int32_t)ures : INT32_MIN + (int32_t)(ures & INT32_MAX);
}

, ( ).

EDIT: , (ures <= INT32_MAX) , (ures < (uint32_t)INT32_MIN) .

+1

- , uint8_t . int32_t 4 uint8_t, , uint8_t int32_t.
uint8_t, int32_t, , , , int32_t, , 4- .

With any of these methods, you will have to prevent you from filling out the array correctly uint8_tto confirm your system.

0
source

Source: https://habr.com/ru/post/1685604/


All Articles