konur 0 Posted June 29, 2016 Share Posted June 29, 2016 Hello everyone; 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. Quote Link to post Share on other sites
Fmilburn 445 Posted June 29, 2016 Share Posted June 29, 2016 What happens if we do this instead? void setup() { long a; byte b = 100; Serial.begin(9600); a = (long)( << 16; Serial.println(a); } void loop() { // put your main code here, to run repeatedly: } tripwire 1 Quote Link to post Share on other sites
abecedarian 330 Posted June 29, 2016 Share Posted June 29, 2016 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. Quote Link to post Share on other sites
tripwire 139 Posted June 29, 2016 Share Posted June 29, 2016 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. abecedarian and Fmilburn 2 Quote Link to post Share on other sites
Fmilburn 445 Posted June 30, 2016 Share Posted June 30, 2016 BTW, welcome to 43oh @@konur. You made an interesting obsevation... Quote Link to post Share on other sites
yyrkoon 250 Posted July 29, 2016 Share Posted July 29, 2016 Shifts should always be enclosed in (). So . . . a = (b << X); Where X is a numerical values in bits to shift left. Quote Link to post Share on other sites
terjeio 134 Posted July 29, 2016 Share Posted July 29, 2016 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" Quote Link to post Share on other sites
yyrkoon 250 Posted July 29, 2016 Share Posted July 29, 2016 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. Quote Link to post Share on other sites
FlaSher2M 0 Posted August 6, 2016 Share Posted August 6, 2016 It interested me. As The good persons Failure is the opportunity to begin again, more intelligently. Henry Ford Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.