Problem with shift operation

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Problem with shift operation

Jump to solution
462 Views
danielecortella
Contributor V

Hi, i have this simple operation : image->start_sector = (((char)(*buff))<<24)|(((char)*(buff+1))<<16)|(((char)*(buff+2))<<8)|((char)*(buff+3));

 

where i concatenate 4 byte in a 32bit variable. the problem is when i shift the buff+1 << 16. The number that i have to obtain could be 0x3b9b2a00 but i have 0xff9b2a00. The problem is visible in the image, the other shift work well.16882_16882.jpgImmagine.JPG.jpg

Labels (1)
0 Kudos
1 Solution
333 Views
BlackNight
NXP Employee
NXP Employee

Hi Daniele,

your code assumes that plain 'char' is unsigned. However, plain char is 'signed', or at least this is what I believe you are using.

Check your compiler settings:

pastedImage_0.png

The correct way to write your calculation is

  result = (((unsigned char)(*buff))<<24)|(((unsigned char)*(buff+1))<<16)|(((unsigned char)*(buff+2))<<8)|((unsigned char)*(buff+3));

Explanation:

*(buff+1)

is a char (signed char)

Then you even cast it to a (signed) char again (redundant from the compiler point of view)

((char)*(buff+1))

Then, before the shift (<<) operation, the compiler has to do integral promotion.

because this is a signed char (0x9b) and negative, it gets promoted to

0xff9b

and then ORed into your result.

So this is why you get 0xff9b.

Solution: take care of signed or unsigned char, and use unsigend char in that particular case.

I hope this helps,

Erich

View solution in original post

0 Kudos
1 Reply
334 Views
BlackNight
NXP Employee
NXP Employee

Hi Daniele,

your code assumes that plain 'char' is unsigned. However, plain char is 'signed', or at least this is what I believe you are using.

Check your compiler settings:

pastedImage_0.png

The correct way to write your calculation is

  result = (((unsigned char)(*buff))<<24)|(((unsigned char)*(buff+1))<<16)|(((unsigned char)*(buff+2))<<8)|((unsigned char)*(buff+3));

Explanation:

*(buff+1)

is a char (signed char)

Then you even cast it to a (signed) char again (redundant from the compiler point of view)

((char)*(buff+1))

Then, before the shift (<<) operation, the compiler has to do integral promotion.

because this is a signed char (0x9b) and negative, it gets promoted to

0xff9b

and then ORed into your result.

So this is why you get 0xff9b.

Solution: take care of signed or unsigned char, and use unsigend char in that particular case.

I hope this helps,

Erich

0 Kudos