3

Hi I have a base 10 number for example 3198, and the hex representation is 0x0C7E

How do I convert that number to hex and put that hex value in a byte array in the format of [00][0C][7E], assuming the biggest hex value i can have is 0xffffff.

kkh
  • 4,799
  • 13
  • 45
  • 73
  • What C data type do you mean by "base 10 number"? C has integer types, and they don't differentiate between 3198 and 0x0C7E. – Klas Lindbäck Dec 02 '11 at 08:26

3 Answers3

9

Maybe this will work ?

uint32_t x = 0x0C7E;
uint8_t bytes[3];

bytes[0] = (x >> 0)  & 0xFF;
bytes[1] = (x >> 8)  & 0xFF;
bytes[2] = (x >> 16) & 0xFF;


/* Go back. */
x = (bytes[2] << 16) | (bytes[1] << 8) | (bytes[0] << 0);
cnicutar
  • 178,505
  • 25
  • 365
  • 392
  • ah nice! thanks sorry i am very noob at C. But how do I convert 3198 to hex? – kkh Dec 02 '11 at 08:16
  • oh another question, if i want o revert the byte array back to the hex format how do i do it? – kkh Dec 02 '11 at 08:19
  • @cnicutar I have a question in your answer. You mean `bytes[0]` as MSB and `bytes[2]` as LSB right? –  Jul 11 '19 at 07:14
1

Number is already a continuous memory block - no need to convert it to yet ANOTHER array ! Just fetch separate bytes by using pointer arithmetic:

EDIT: Edited to be endianness-independent

#define FAST_ABS(x) ((x ^ (x>>31)) - (x>>31))

int is_big_endian(void)
{
    union {
        uint32_t i;
        char c[4];
    } bint = {0x01020304};

    return bint.c[0] == 1; 
}    

uint32_t num = 0xAABBCCDD;
uint32_t N = is_big_endian() * 3;

printf("first byte 0x%02X\n"
       "second byte 0x%02X\n"
       "third byte 0x%02X\n"
       "fourth byte 0x%02X\n",
       ((unsigned char *) &num)[FAST_ABS(3 - N)],
      ((unsigned char *) &num)[FAST_ABS(2 - N)],
      ((unsigned char *) &num)[FAST_ABS(1 - N)],
      ((unsigned char *) &num)[FAST_ABS(0 - N)]
       );
Agnius Vasiliauskas
  • 10,935
  • 5
  • 50
  • 70
  • Endianness-dependent. If you run this on a SPARC or PPC system (big-endian), you're getting the reverse. – FrankH. Dec 02 '11 at 09:35
  • See edit. I'v changed it to be endianness-invariant. Endianess check idea is taken from [here](http://stackoverflow.com/questions/1001307/detecting-endianness-programmatically-in-a-c-program) – Agnius Vasiliauskas Dec 02 '11 at 10:32
  • A complex solution to a problem that doesn't exist if you program in a portable way to start with, re - cnicutar's answer. I give you a +1 for shrewed persistence ;-) – FrankH. Dec 02 '11 at 11:06
  • I totally agree :-) I just wanted to show that in C - everything is bits and bytes - only interpretation of them is what really matters for compilers. That's the main power of C which i love most {and while others hate it and call it "non-existance of type system" in C :-) } – Agnius Vasiliauskas Dec 02 '11 at 11:21
0
#include <stdio.h>

union uint32_value {
    unsigned int value;

    struct little_endian {
        unsigned char fou;
        unsigned char thi;
        unsigned char sec;
        unsigned char fir;
    } le;

    struct big_endian {
        unsigned char fir;
        unsigned char sec;
        unsigned char thi;
        unsigned char fou;
    } be;
};

int main(void)
{
    union uint32_value foo;
    foo.value = 3198;
    printf("%02x %02x %02x %02x\n", foo.le.fir, foo.le.sec, foo.le.thi, foo.le.fou);

    return 0;
}
arnkore
  • 425
  • 5
  • 14