简体   繁体   中英

How do I use bitwise shifts with cout?

I'm trying to do something similar to this:

#include <iostream>

int main()
{
    std::cout << 1 << 5 << std::endl;
}

I expect 32 (1 shifted left by 5), but I get 15.

I am trying to use a macro like this:

#define BIT_SHIFT(x,y) x << y
...
cout << BIT_SHIFT(1, 5) << std::endl;

and this happens.

Why? How do I fix this?

Just use parentheses:

#include <iostream>

int main()
{
    std::cout << (1 << 5) << std::endl;
}

std::cout << 1 << 5 means "push to output stream first integer literal 1 , followed by integer 5 ". However, adding parantheses changes the order of evaluation, and 1 << 5 is evaluated first, resulting in std::cout << 32 << std::endl; expression.

Use parenthesis:

    std::cout << (1 << 5) << std::endl;

The reason is that the output ostream& operator<<(ostream&, const T&) overload chains the return values to call the function once more.

If you use parenthesis, the bitshift value is calculated first, and then passed to the overloaded output operator.


I am trying to use this in a macro: ...

Thus the above said your macro definition should look like:

#define BIT_SHIFT(x,y) ((x) << (y))

You may wonder why the extra parenthesis now. This is just safer writing macros. Think about someone tries to use your macro like:

 cout << BIT_SHIFT(1, 5*2) << std::endl;

I'm trying to do something similar to this:

 #include <iostream> int main() { std::cout << 1 << 5 << std::endl; }

You're right. You are trying to do something similar to that. However, the problem has nothing to do with the macro (I mean, that's a problem too, but more on that later). The problem is your goal isn't what you mean. You don't mean std::cout << 1 << 5 << std::endl; , you mean std::cout << (1 << 5) << std::endl; The difference is that the first breaks down into something like this:

std::cout << 1;
std::cout << 5;
std::cout << std::endl;

While what you want is something like this:

int i = 1 << 5;

std::cout << i;
std::cout << std::endl;

Or something to that effect.

The answer is simple: either use parenthesis in your cout statement, or put it in your macro (the better option):

// either 
cout << (BIT_SHIFT(1, 5)) << std::endl;
// or
#define BIT_SHIFT(x,y) (x << y)
...
cout << BIT_SHIFT(1, 5) << std::endl;

Also, as someone else suggested, you can even go a step further if you like and do this:

#define BIT_SHIFT(x,y) ((x) << (y))
...
cout << BIT_SHIFT(1, 5) << std::endl;

That way, if you do something weird in x or y , your code doesn't break.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM