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.