skip to Main Content
#include <stdio.h>
#include <time.h>
#include <stdlib.h>

#define COUNTS 1000000

int f2() 
{
    struct timespec ts;

    if (clock_gettime(CLOCK_REALTIME, &ts) == -1) 
    {
        perror("clock_gettime");
        return 1;
    }
    
    srand(ts.tv_nsec);

    int num;
    do
    {
        num = (int)((double) (rand() / ((double)RAND_MAX + 1.0))*5) + 1;
    } while (num == 3);

    return (num > 3) ? 1 : 0;
}


int f3()
{
    printf("a. %dn",(f2()<<2 + f2()<<1 + f2()));
    printf("b. %dn",((int)(f2()<<2) + (int)(f2()<<1) + (int)f2()));
    return ((int)(f2()<<2) + (int)(f2()<<1) + (int)f2());
    // return (f2()<<2 + f2()<<1 + f2());
}

int main()
{
    for (int i = 0; i < COUNTS; i++)
    {
        f3();
    }

    return 0;
}

When I run the program above, it will print

a. 8
b. 3
a. 0
b. 6
a. 16
b. 1
a. 16
b. 1
a. 0
b. 6
a. 0
b. 6
a. 32
b. 0
a. 32
b. 4
a. 32
b. 6
a. 0
b. 0
a. 16
b. 7
a. 16
b. 5
a. 0
b. 4
a. 8
b. 6
a. 8
b. 1
a. 32
b. 3
a. 16
b. 7
a. 0
b. 7
a. 0
b. 2
a. 16
b. 2
a. 32
b. 6
a. 0
b. 6
a. 0
b. 3
a. 0
b. 1
a. 8
b. 4
a. 0
b. 2
a. 16
b. 4

When I run the above program, the print is as follows. I ensure that the f2 function returns only 0 and 1, and after calling the f2 function, perform bitwise operations. Why does the first printf print 16 and 32, even if f2 returns 1 for all, the maximum value should only be 7? The return value of the second printf looks correct. Why is this

The platform I am on is Ubuntu 20.04

I want to know if such a result has occurred

2

Answers


  1. If you turn warnings on, the compiler will tell you (at least mine does):

    $ gcc -Wall 1.c
    1.c: In function ‘f3’:
    1.c:31:31: warning: suggest parentheses around ‘+’ inside ‘<<’ [-Wparentheses]
         printf("a. %dn",(f2()<<2 + f2()<<1 + f2()));
                                 ~~^~~~~~
    1.c:31:41: warning: suggest parentheses around ‘+’ inside ‘<<’ [-Wparentheses]
         printf("a. %dn",(f2()<<2 + f2()<<1 + f2()));
                                           ~~^~~~~~
    

    It’s a precedence problem! The addition happens before the bit shift. Use parentheses to fix it.

    -    printf("a. %dn",(f2()<<2 + f2()<<1 + f2()));
    +    printf("a. %dn",((f2()<<2) + (f2()<<1) + f2()));
    
    Login or Signup to reply.
  2. Because shift operators and arithmetic operators have different precedence when no parentheses are specified. In fact in the printf() .b the values ​​you can observe are in the range [0,7].

    This is a reference on the precedence given to operators.

    I recommend that you enable all compiler warnings and errors and use a debugger to step through your code.

    When you get unexpected behavior, the first thing you need to do is make the code output reproducible. In this case you should eliminate rand(), which generates pseudorandom numbers, to be able to find the problem, or change its usage, as in the following code.

    A playground example with explicit parentheses. This is your code slightly modified to allow you to compare the two printf()s, and see how the compiler groups the operands.

    The interested code:

    int f3()
    {
        int v1 = f2(), v2 = f2(), v3 = f2();
        printf("a. %d %dn",v1<<2 + v2<<1 + v3, // as you wrote
                v1<<(2 + v2)<<(1 + v3));        // how the compiler interprets it
        printf("b. %dn",(int)(v1<<2) + (int)(v2<<1) + (int)v3);
        return ((int)(v1<<2) + (int)(v2<<1) + (int)v3);
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search