Be cautious when iterating bit-shifts

Discussion in 'C Programming' started by geo, Nov 16, 2009.

  1. geo

    geo Guest

    #include <stdio.h>
    int main()
    { int x=2048;
    printf("%d\n",x);
    printf("%d\n",((x<<2)>>2) );
    printf("%d\n", (x<<2)>>2 );
    printf("%d\n",((x<<2)>>2)-x );
    printf("%d\n", (x<<2)>>2 -x );
    }

    Can you predict what five integers
    will result from compiling and running
    the above program?
    Will all compilers give the same results?
     
    geo, Nov 16, 2009
    #1
    1. Advertising

  2. geo

    Noob Guest

    geo wrote:

    > #include <stdio.h>
    > int main()
    > { int x=2048;
    > printf("%d\n",x);
    > printf("%d\n",((x<<2)>>2) );
    > printf("%d\n", (x<<2)>>2 );
    > printf("%d\n",((x<<2)>>2)-x );
    > printf("%d\n", (x<<2)>>2 -x );
    > }
    >
    > Can you predict what five integers
    > will result from compiling and running
    > the above program?
    > Will all compilers give the same results?


    $ cat foo.c
    #include <stdio.h>
    int main(void)
    {
    int x=2048;
    printf("%d\n",x);
    printf("%d\n",((x<<2)>>2) );
    printf("%d\n", (x<<2)>>2 );
    printf("%d\n",((x<<2)>>2)-x );
    printf("%d\n", (x<<2)>>2 -x );
    return 0;
    }

    $ gcc -std=c89 -pedantic -Wall -Wextra foo.c
    foo.c: In function 'main':
    foo.c:9: warning: suggest parentheses around + or - inside shift

    ===> NB gcc's suggestion <===

    $ ./a.out
    2048
    2048
    2048
    0
    2048

    INT_MAX must be at least 32767.
    2048 << 2 equals 8192, thus x << 2 is always well-defined.
    Let y = x << 2

    You're considering
    1. (y >> 2)
    2. y >> 2
    3. (y >> 2) - x
    4. y >> 2 - x

    1. and 2. are obviously equivalent, and equal to x.
    3. is equivalent to x - x i.e. 0.
    4. is equivalent to y >> (2-x) which is undefined.

    Regards.
     
    Noob, Nov 16, 2009
    #2
    1. Advertising

  3. geo

    Eric Sosman Guest

    geo wrote:
    > #include <stdio.h>
    > int main()
    > { int x=2048;
    > printf("%d\n",x);
    > printf("%d\n",((x<<2)>>2) );
    > printf("%d\n", (x<<2)>>2 );
    > printf("%d\n",((x<<2)>>2)-x );
    > printf("%d\n", (x<<2)>>2 -x );
    > }
    >
    > Can you predict what five integers
    > will result from compiling and running
    > the above program?


    No: Undefined behavior is not predictable. Not on the
    basis of the C language, at any rate, although it might be
    possible to predict the outcome for a given implementation.

    > Will all compilers give the same results?


    Unlikely: Undefined behavior is not guaranteed to be
    consistent.

    --
    Eric Sosman
    lid
     
    Eric Sosman, Nov 16, 2009
    #3
  4. geo

    Phil Carmody Guest

    geo <> writes:
    > printf("%d\n",((x<<2)>>2)-x );


    Don't mix bit-wise operations with arithmetic operations
    unless you have an over-riding need to.

    << >> & | ^: fine
    * / % + - : fine

    Cross-pollination leads to mutants.

    Phil
    --
    Any true emperor never needs to wear clothes. -- Devany on r.a.s.f1
     
    Phil Carmody, Nov 19, 2009
    #4
  5. geo

    Phil Carmody Guest

    Richard Heathfield <> writes:
    > In <>, Phil Carmody wrote:
    >
    >> geo <> writes:
    >>> printf("%d\n",((x<<2)>>2)-x );

    >>
    >> Don't mix bit-wise operations with arithmetic operations
    >> unless you have an over-riding need to.
    >>
    >> << >> & | ^: fine
    >> * / % + - : fine

    >
    > Got me. I put my head on my left shoulder, trying to work out what
    > kind of smileys they were.
    >
    >> Cross-pollination leads to mutants.

    >
    > And thus to fitter life-forms. Analogies can be dangerous! :)


    Absolutely, "(1u<<n)-1" has great longevity for a reason.

    Phil
    --
    Any true emperor never needs to wear clothes. -- Devany on r.a.s.f1
     
    Phil Carmody, Nov 21, 2009
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Reid Nichol
    Replies:
    11
    Views:
    1,182
    Francesco Bochicchio
    Sep 11, 2004
  2. Ross A. Finlayson
    Replies:
    19
    Views:
    604
    Keith Thompson
    Mar 10, 2005
  3. gamehack

    Bit shifts and endianness

    gamehack, Jan 5, 2006, in forum: C Programming
    Replies:
    72
    Views:
    6,871
    Dave Thompson
    Jan 11, 2006
  4. fermineutron

    bit shifts across array elements

    fermineutron, Nov 4, 2006, in forum: C Programming
    Replies:
    6
    Views:
    355
    Peter Nilsson
    Nov 6, 2006
  5. www
    Replies:
    4
    Views:
    2,155
    Eric Sosman
    Apr 19, 2007
Loading...

Share This Page