about right-shift operator >> in C++ - c++

Here is a C++ program I see today:
for (int i = 0; i < LEVELS; ++i)
{
int pyr_rows = rows >> i; // what is the usage of >> i here ?
int pyr_cols = cols >> i; // why we what to use it in this way.
depths_curr_[i].create (pyr_rows, pyr_cols);
}
What I am curious about is the usage of operator >> here. I tried a simple program and type the results:
int rows = 5;
int cols = 3;
for (int i=0; i<5; i++)
{
int pyr_rows = rows >> i;
std::cout << "current i is:" << i << std::endl;
std::cout << "pyr_rows is: " << pyr_rows << std::endl << std::endl;
int pyr_cols = cols >> i;
std::cout << "current i is:" << i << std::endl;
std::cout << "pyr_cols is: " << pyr_cols << std::endl << std::endl;
}
And the result is like this:
current i is:0
pyr_rows is: 5
current i is:0
pyr_cols is: 3
current i is:1
pyr_rows is: 2 // from now on
// the outputs of pyr_rows and pyr_cols are weird to me
current i is:1
pyr_cols is: 1
current i is:2
pyr_rows is: 1
current i is:2
pyr_cols is: 0
current i is:3
pyr_rows is: 0
current i is:3
pyr_cols is: 0
current i is:4
pyr_rows is: 0
current i is:4
pyr_cols is: 0
Why the output is like this? Can anyone explain it? And why we want to use this in this way? Any situation we prefer to do it?

It's not the "extraction operator", it's the right-shift operator, which is what >> meant before C++ started inventing crazy ways to overload it. I'm guessing from the pyr that this is pyramidal image processing? The idea is that every time i increases by one, the number of rows and columns in the pyramid are halved. That's because a right shift by i is basically a division (rounding down) by 2^i.

In the case you've outlined, >> stands for the right shift operator. If you consider an integer written in binary form:
01101 = 13
The >> i operator will make the bits above be shifted towards the right i times. So when i = 2, the above would result in:
00011 = 3
This is useful to efficiently divide integers by powers of 2. The result ends up rounded down, so 3 >> 1 equals 1, but -3 >> 1 equals -2.
This is the arithmetic shift, which means the leading bit gets padded, so that negative numbers can remain negative after the shift (leading bit 1). Some languages also have the >>> operator for the logical shift, which always pads the leading bits with zeroes.

It is not an "extraction operator", it is the original bitwise shift (right) operator, that was in C before anyone had even considered making a C++ language. It is now being used as an operator for files to input and output.
int x = 4;
int y = 1;
cout << (x >> y) << endl;
will produce 4 shifted right 1 bit, which should show the value 2.

Related

Using Left Shift operator with ones at the right of the number

I'm not very familiar with bit operators and I have this use case : when we use the left shift operator << in C++ the number will be shifted and 0 will be placed at the right of number, I want to place 1 and not zero at the right.
I mean if I have a number 00000000 and I make << 3 the result need to be 00000111 and not 0 !
Simple approach is to left shift 1 by the number of bits you want set and then subtract 1
(1 << n) - 1
E.g.
cout << (1 << 2) - 1 << '\n'; // prints 3
cout << (1 << 3) - 1 << '\n'; // prints 7
cout << (1 << 4) - 1 << '\n'; // prints 15
cout << (1 << 5) - 1 << '\n'; // prints 31
But note this only works if n is less than the number of bits in an integer. Otherwise it's undefined behaviour.
Here's a solution that works on any number:
int one_shift(int val, int n) {
return ~(~0 << n) | (val << n);
}
Breakdown:
~0 evaluates to 0xFFFFFFFF e.g. all 1's
~0 << n shifts 0xFFFFFFFF by N places, resulting in a number with N zeroes on the end
~(~0 << n) flips all these bits, resulting in a number with only the last N bits set
| (val << n) then does a regular left shift on our original number by N places, and sets the last N bits by oring it with our other value
Also, here's a version that works on any integer type:
template<typename T>
T one_shift(T val, int n) {
return ~(~static_cast<T>(0) << n) | (val << n);
}
Then that's not what a left shift is.
You will have to set those bits to 1 yourself.

Need an explanation on a shift syntax in code - C++ [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I need some further explanation on a code I don't quite understand.
This is a program that takes a num = 25 and starts moving it left with a << syntax.
#include <iostream>
using namespace std;
int main(){
cout << "Shift to the left" << endl;
short numb = 25;
cout << "Starting value: ";
for (int i = sizeof(short)*8 - 1; i >= 0; i--)
cout << (((1 << i) & numb) == 0 ? "0" : "1");
cout << " " << numb << endl;
for (int i = 0; i < sizeof(short)*8; i++){
numb <<= 1;
cout << "Shift" << (i+1 < 10 ? "0" : "")
<< i+1 << " : ";
for (int i = sizeof(short)*8 - 1; i >= 0; i--)
cout << (((1 << i) & numb) == 0 ? "0" : "1");
cout << " " << numb << endl;
}
return 0;
}
After the line where the first for loop is executed (the count line), what value does the & syntax takes into consideration? ((1 << i) & numb)
I don't understand how the program can take ((1 << i) & numb), compares the two and return a value.
Also why do we declare i to be sizeof(short)*8 - 1? Why don't we just type in 16-1? Is there a specific reason to do this or is it just to make the code look more complex?
And an explanation on why we even declare i to be 15-1 would be highly appreciative.
Hope I haven't given you too much, I'm a beginner and I need some guidance with some problems to which answers I can't still yet come up with by myself.
Thanks!
The bitwise shift operators are the right-shift operator (>>), which moves the bits of shift_expression to the right, and the left-shift operator (<<), which moves the bits of shift_expression to the left. There are also two complex operators that can be used to assign the value directly to the value on left. These are the <<= operator and the >>= operator.
The left-shift operator causes the bits in shift-expression to be shifted to the left by the number of positions specified by additive-expression. The bit positions that have been vacated by the shift operation are zero-filled. A left shift is a logical shift (the bits that are shifted off the end are discarded, including the sign bit).
The right-shift operator causes the bit pattern in shift-expression to be shifted to the right by the number of positions specified by additive-expression. For unsigned numbers, the bit positions that have been vacated by the shift operation are zero-filled. For signed numbers, the sign bit is used to fill the vacated bit positions. In other words, if the number is positive, 0 is used, and if the number is negative, 1 is used.
Demo Code:
using namespace std;
int main() {
int a = 1, b = 3;
// a right now is 00000001
// Left shifting it by 3 will make it 00001000, ie, 8
a = a << 3;
cout << a << endl; // Gives output 8
// Right shifting a by 2 will make it 00000010, ie, 2
a = a >> 2;
cout << a << endl; // Gives output 2
return 0;
}
The result of a right-shift of a signed negative number is implementation-dependent. If you left-shift a signed number so that the sign bit is affected, the result is undefined.

Weird mistake in taking the sums of elements in alglib::real_1d_array

OK this time I have a really weird mistake that does not always appear. Here is the function that actually contains problems. All it does is literally summing elements of a vector. It works in most cases but in a few cases it tend to become highly problematic.
int sumvec(vect v) {
int i = 0;
int sum = 0;
int l = v.length();
std::cout << "Sum of vector " << v.tostring(3) << std::endl;
for (; i < l; i++) {
sum += v[i];
std::cout << v[i] << " " << sum << " ";
};
std::cout << std::endl;
return sum;
}
Here vect is defined using typedef alglib::real_1d_array vect;. OK so what do I get? Huh..
Sum of vector [1.000,1.000,0.000,1.000,1.000,1.000]
1 0 1 0 0 0 1 0 1 0 1 1
What?!!!!!
As your sum variable is an integer you may not get the expected results when summing elements in your vector which are not integers.
If your elements have the value of 0.999999999 rather than 1.00000 then printing them could be rounded to 1.00000 but when you add them to an integer the value will be truncated to 0.
Judging by the provided output all of your values are less than 1 apart from the last one which is greater or equal to 1.
There are 2 possible solutions:
Change the type of sum to be float or double.
Change your calculation to: sum += static_cast<int>(round( v[i] ));
Note that your compiler was probably warning about the truncation of a double to an integer. Pay attention to compiler warnings, they often indicate a bug.
As commented use a double to store the sum if you are working with floating point integers. using an integer will cause the variable to be implicitely casted to an int which just cuts of the mantissa:
0.9999998 -> 0
Depending on cout::precision, 0.99999 would be printed as 1.0000(rounded) or without std::fixed just as 1 what propably happens in your example.
double a = 0.999;
std::cout.precision(2);
std::cout << a << std::endl; /* This prints 1 */
std::cout << std::fixed;
std::cout << a << endl; /* This prints 1.00 */

C++ giving a negative number when I square

So I have some code that is supposed to be giving me the points on a parabola but the problem is that when I square the number when it is a negative it gives me a negative back which wont work.
#include "TileClass.h"
//#include <cmath> included in other header
// Original equation y=-x^2+4
void Tile::Loc() {
for (int a = -2; a < 3; a = a + 1) {
cout << "--- " << a << endl;
cout << "Pw" << (a << 2) << endl;
cout << ((a << 2) + 4) << endl;
}
}
output
--- -2
Pw-8
-4
--- -1
Pw-4
0
--- 0
Pw0
4
--- 1
Pw4
8
--- 2
Pw8
12
The C++ operator << is not the square operator. It is the bitshift operator.
Try
-(a*a)+4
instead
The express a<<2 will shift each bit of a to left by 2, which means a*4
And if you want to get the square of a, you had better use a*a.
it doesn't look like you're squaring. You're left shifting the binary value which is essentially the same as multiplying by 2 per left shift. So when a = -2, doing (a << 2) should result in -8 being displayed. What you are looking for is the pow() function found in the cmath library which should be used like this pow(a, 2);

Thinking in C++ shift operators

I'm reading through a book on C++ standards: "Thinking in C++" by Bruce Eckel.
A lot of the C++ features are explained really well in this book but I have come to a brick wall on something and whether it may or may not help me when I wish to program a game for example, it's irking me as to how it works and I really cannot get it from the explanation given.
I was wondering if anybody here could help me in explaining how this example program actually works:
printBinary.h -
void printBinary(const unsigned char val);
printBinary.cpp -
#include <iostream>
void printBinary(const unsigned char val) {
for (int i = 7; i >= 0; i--) {
if (val & ( 1 << i))
std::cout << "1";
else
std::cout << "0";
}
}
Bitwise.cpp -
#include "printBinary.h"
#include <iostream>
using namespace std;
#define PR(STR, EXPR) \
cout << STR; printBinary(EXPR); cout << endl;
int main() {
unsigned int getval;
unsigned char a, b;
cout << "Enter a number between 0 and 255: ";
cin >> getval; a = getval;
PR ("a in binary: ", a);
cin >> getval; b = getval;
PR ("b in binary: ", b);
PR("a | b = ", a | b);
This program is supposed to explain to me how the shift bitwise operator (<<) and (>>) work but I simply don't get it, I mean sure I know how it works using cin and cout but am I stupid for not understanding this?
this piece in particular confuses me more so than the rest:
if (val & ( 1 << i))
Thanks for any help
if (val & ( 1 << i))
Consider the following binary number (128):
10000000
& is bitwise "AND" - 0 & 0 = 0, 0 & 1 = 1 & 0 = 0, 1 & 1 = 1.
<< is bitwise shift operator; it shifts the binary representation of the shifted number to left.
00000001 << 1 = 00000010; 00000001 << 2 = 00000100.
Write it down on a piece of paper in all iterations and see what comes out.
1 << i
takes the int-representation of 1 and shifts it i bits to the left.
val & x
is a bit-wise AND between val and x (where x is 1 << i in this example).
if(x)
tests if x converted to bool is true. Any non-zero value of an integral type converted to bool is true.
<< has two different meanings in the code you shown.
if (val & (1 << i))
<< is used to bitshift, so the value 1 will be shifted left by i bits
cout << ....
The stream class overloads the operator <<, so here it has a different meaning than before.
In this case, << is a function that outputs the contents on its right to cout
if (val & ( 1 << i))
This checks if the bit in i-th position is set. (1 << i) is something like 000001000 for i = 3. Now if the & operation returns non-zero, that means val had the corresponding bit set.