• AVR Freaks

Hot!Unexpected 32-bit results from left shift operator in XC8 v2.20

Author
JohnBend
New Member
  • Total Posts : 26
  • Reward points : 0
  • Joined: 2009/08/25 05:58:49
  • Location: UK
  • Status: offline
2020/06/23 06:23:02 (permalink)
0

Unexpected 32-bit results from left shift operator in XC8 v2.20

I am getting unexpected results from left ship operator in XC8 v2.20. The following examples can be run in simulator mode.
 
Is the << operator 8-bit and 16-bit only?
unsigned char TestChar;
unsigned short TestShort;
unsigned long TestLong;

    TestChar = 0;
    TestChar |= (1 << 7);
    /* Result = 10000000 */

    TestShort = 0;
    TestShort |= (1 << 15);
    /* Result = 10000000 00000000 */

    TestLong = 0;
    TestLong |= (1 << 15);
    /* Result = 11111111 11111111 10000000 00000000 */


Good, fast, cheap - pick any two.

#1

4 Replies Related Threads

    andersm
    Super Member
    • Total Posts : 2822
    • Reward points : 0
    • Joined: 2012/10/07 14:57:44
    • Location: 0
    • Status: online
    Re: Unexpected 32-bit results from left shift operator in XC8 v2.20 2020/06/23 06:30:46 (permalink)
    +3 (3)
    The expression "(1 << 15)" has the type int, and is being sign-extended into a long. Try
    TestLong |= (1UL << 15);

    #2
    JohnBend
    New Member
    • Total Posts : 26
    • Reward points : 0
    • Joined: 2009/08/25 05:58:49
    • Location: UK
    • Status: offline
    Re: Unexpected 32-bit results from left shift operator in XC8 v2.20 2020/06/23 07:40:53 (permalink)
    +1 (1)
    Thank you very much.

    Good, fast, cheap - pick any two.

    #3
    1and0
    Access is Denied
    • Total Posts : 10906
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Unexpected 32-bit results from left shift operator in XC8 v2.20 2020/06/23 07:47:54 (permalink)
    +2 (2)
    That is because an unsuffixed 1 is a signed int, so the result of (1 << 15) is an int. When this int is assigned to a long, it is sign-extended (according to the C standard) as Andersm said.
     
    Edit:
    JohnBend
    Is the << operator 8-bit and 16-bit only?

    No.
    unsigned long TestLong;

        TestLong = 0;
        TestLong |= (1UL << 31);
        /* Result = 10000000 00000000 00000000 00000000 */

     
    post edited by 1and0 - 2020/06/23 08:03:19
    #4
    ric
    Super Member
    • Total Posts : 27652
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: Unexpected 32-bit results from left shift operator in XC8 v2.20 2020/06/23 15:50:42 (permalink)
    +2 (2)
    A bad assumption many newcomers to C make is, thinking the size of an expression is controlled by the size of the variable to the left of the "=".
    In fact, that is irrelevant, the expression is evaluated by ONLY looking at what appears to the right of the equals, using the size of the largest operand.
    Only when the calculation is complete, does it attempt to cram the result into the variable on the left, at which time sign extension may occur.
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #5
    Jump to:
    © 2020 APG vNext Commercial Version 4.5