0

I don't know if the question is right, but.

Example, a decimal of 25441, the binary is 110001101100001. How can i split it into two 8 bit "1100011" and "01100001"( which is "99" and "97"). However, I could only think of using bit manipulation to shift it by >>8 and i couldn't do the rest for "97". Here is my function, it's not a good one but i hope it helps:

void reversecode(int input[], char result[]) {  //input is 25441
int i;
for (i = 0; i < 1; i++) {  
    result[i] = input[i] >> 8;                  // shift by 8 bit
    printf("%i", result[i]);                    //to print result
}
}

I was thinking to use struct but i have no clue for starting it. i'm a beginenr in C, and sorry for my bad style. Thank you in prior.

Lactobacillus
  • 27
  • 1
  • 1
  • 7

2 Answers2

9

The LSB is given simply by masking is out with a bit mask: input[i] & 0xFF.

The code you have posted input[i] >> 8 gives the next byte before that. However, it also gives anything that happened to be stored in the most significant bytes, in case int is 32 bits. So again you need to mask, (input[i] >> 8) & 0xFF.

Also avoid bit-shifting on signed types such as int, because if they have negative values, you invoke poorly-specified behavior which leads to bugs.

The correct way to mask out the individual bytes of an int is this:

// 16 bit system  
uint8_t bytes [sizeof(int)] = 
{
  ((uint16_t)i >> 0) & 0xFF,  // shift by 0 not needed, of course, just stylistic
  ((uint16_t)i >> 8) & 0xFF,
};

// 32 bit system  
uint8_t bytes [sizeof(int)] = 
{
  ((uint32_t)i >>  0) & 0xFF,
  ((uint32_t)i >>  8) & 0xFF,
  ((uint32_t)i >> 16) & 0xFF,
  ((uint32_t)i >> 24) & 0xFF,
};

This places the LSB at index 0 in this array, similar to Little Endian representation in memory. Note however that the actual bit-shift is endianess-independent, and also fast, which is why it's a superior method.

Solutions based on unions or pointer arithmetic depend on endianess and are often buggy (pointer aliasing violations), so they should be avoided, as there is no benefit of using them.

Lundin
  • 195,001
  • 40
  • 254
  • 396
2

you can use the bit-masking concept.
Like this,

uint16_t val = 0xABCD;
uint8_t vr  = (uint8_t) (val & 0x00FF);

Or this can also be done by simply explicit type casting, as an 8-bit integer only carries LBS 8-bits from 16-bits value, & discards the remaining MSB 8-bits (by default, when assigns a larger value). This all done after shifting of bits.

Waqas Shabbir
  • 755
  • 1
  • 14
  • 34
  • I don't know if I'm supposed to say this but, I am not allowed to use what I haven't learned. So after it shifts 8 bits, how could i discard the remaining MSB 8- bits? (sorry kinda clueless). – Lactobacillus Nov 19 '18 at 03:27
  • by shifting (8 times obviously), the MSB 8 bits are now are LSB with MSB as zeros. now move this value to any of 8 bit data type, this discards the MSB zeros and the remaining is your value. – Waqas Shabbir Nov 19 '18 at 04:24