Jump to content

Recommended Posts

Hello everyone;

 

post-49019-0-06869000-1467221628_thumb.png

 

As you can see bitshifting a byte 16 bits and storing in a long doesn't seem to work, while shifting storing and shifting again works perfectly. Is this behaviour normal?

 

Using energia 0101e0017 on win7 with msp430g2553 launchpad.

 

Also i'm not 100% sure but i think bitshifting 16 bits worked fine on a tm4c123gxl launchpad because i ran into this while converting a code that was written for tm4c to msp.

post-49019-0-06869000-1467221628_thumb.png

Share this post


Link to post
Share on other sites

msp430 have an intrinsic, native 16 bit depth, so a byte is 8 bits out of 16. Shift a byte 16 bits to the left, or right for that matter, and wouldn't you be left with what you started with?... I mean if the compiler uses a rotate rather than a shift and discard bits if the shift is the same as the intrinsic....?

 

Ignore me; I'm an idiot. ;)

Share this post


Link to post
Share on other sites

This is down to the subtleties of integral promotions in C. The standard says this for the bitwise shift operators:

 

"The integral promotions are performed on each of the operands.  The type of the result is that of the promoted left operand.  If the value of the right operand is negative or is greater than or equal to the width in bits of the promoted left operand, the behavior is undefined."

 

Integral promotion can "widen" a type as far as unsigned int, which is 16 bits on MSP430. The RHS of the shift is 16, so that means undefined behaviour; in this case that seems to mean (100 << 16) == 100.

Share this post


Link to post
Share on other sites

Shifts should always be enclosed in (). So  . . . a = (b << X); Where X is a numerical values in bits to shift left.

 

This does not help a bit when shifting a byte by more than 7 - you still need to promote the underlying variable to one big enough to hold the result before doing the shift.

The solution provided by @@Fmilburn does work as does a = (long)b << 16;

 

The compiler even warns about this (I am using CCS): "#64-D shift count is too large"

Share this post


Link to post
Share on other sites

This does not help a bit when shifting a byte by more than 7 - you still need to promote the underlying variable to one big enough to hold the result before doing the shift.

The solution provided by @@Fmilburn does work as does a = (long)b << 16;

 

The compiler even warns about this (I am using CCS): "#64-D shift count is too large"

Oh, right. I missed that. Yeah, shifting a byte 16 bits won't work heh. I experienced a similar effect, but with gcc, and uint32_t a couple years ago. Was discussed here on the forums. gcc as I recall would error if shifting right more than the variable width. but would fail silently when shifting left.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...