What does >> do in this situation?
int n = 500;
unsigned int max = n>>4;
cout << max;
It prints out 31.
What did it do to 500 to get it to 31?
Bit shifted!
Original binary of 500:
111110100
Shifted 4
000011111 which is 31!
Original: 111110100
1st Shift:011111010
2nd Shift:001111101
3rd Shift:000111110
4th Shift:000011111 which equals 31.
This is equivilent of doing integer division by 16.
500/16 = 31
500/2^4 = 31
Some facts pulled from here: http://www.cs.umd.edu/class/spring2003/cmsc311/Notes/BitOp/bitshift.html (because blarging from my head results in rambling that is unproductive..these folks state it much cleaner than i could)
Shifting left using << causes 0's to be shifted from the least significant end (the right side), and causes bits to fall off from the most significant end (the left side).
Shifting right using >> causes 0's to be shifted from the most significant end (the left side), and causes bits to fall off from the least significant end (the right side) if the number is unsigned.
Bitshifting doesn't change the value of the variable being shifted. Instead, a temporary value is created with the bitshifted result.
500 got bit shifted to the right 4 times.
x >> y mathematically means x / 2^y.
Hence 500 / 2^4 which is equal to 500 / 16. In integer division the result is 31.
It divided 500 by 16 using integer division.
>> is a right-shift operator, which shifted the bits of the binary representation of n to the right 4 times. This is equivalent to dividing n by 2 4 times, i. e. dividing it by 2^4=16. This is integer division, so the decimal part got truncated.
It shifts the bits of 500 to the right by 4 bit positions, tossing out the rightmost bits as it does so.
500 = 111110100 (binary)
111110100 >> 4 = 11111 = 31
111110100 is 500 in binary. Move the bits to the right and you are left with 11111 which is 31 in binary.
500 in binary is [1 1111 0100]
(4 + 16 + 32 + 64 + 128 + 256)
Shift that to the right 4 times and you lose the lowest 4 bits, resulting in:
[1 1111]
which is 1 + 2 + 4 + 8 + 16 = 31
You can also examine it in Hex:
500(decimal) is 0x1F4(hex).
Then shift to the right 4 bits, or one nibble:
0x1F == 31(dec).
The >> and << operators are shifting operators.
http://www-numi.fnal.gov/offline_software/srt_public_context/WebDocs/Companion/cxx_crib/shift.html
Of course they may be overloaded just to confuse you a little more!
C++ has nice classes to animate what is going on at the bit level
#include <bitset>
#include <iostream>
int main() {
std::bitset<16> s(500);
for(int i = 0; i < 4; i++) {
std::cout << s << std::endl;
s >>= 1;
}
std::cout << s
<< " (dec " << s.to_ulong() << ")"
<< std::endl;
}
Related
this is a test program to try to get my bitwise shift operations to work. I am hoping to add this to my cache simulator program, but I can't even get this part to work. My plan is to use bit shift (<<) and (>>) to isolate parts of a given memory address (tag, set, word, etc.) but it seems that in shifting the bits back right, it is filling with the values which were previously there, rather than with 0's. Here is the program first.
#include<iostream>
#include <cmath>
struct Address{
unsigned int tag;
unsigned int r;
unsigned int word;
};
int main(){
unsigned int tempAddress = 27; //0011011
int ramSize = 128;
int cacheSize = 64;
int blockSize = 8;
int cacheLines = cacheSize / blockSize;
int addressLength = log(ramSize)/log(2);
int wordBits = log(blockSize)/log(2);
int rBits = log(cacheLines)/log(2);
int tagBits = addressLength - (wordBits + rBits);
struct Address address;
address.tag = tempAddress >> (rBits + wordBits);
address.r = tempAddress << (tagBits) >> (tagBits + wordBits);
address.word = tempAddress << (rBits + tagBits) >> (rBits + tagBits);
std::cout << "tag is: " << address.tag << "\n";
std::cout << "r is: " << address.r << "\n";
std::cout << "word is: " << address.word << "\n";
}
I've found that when my tempAddress is [0-7] it works fine because binary 7 only affects the first 3 bits.
Similarly, when it is [8-63], tag and r are correct because 63 affects the first 6 bits.
Upon testing many addresses, I've found that when shifting right after shifting left, the bits are being replaced with what they were before, rather than with 0s as I think they should be.
(r is the part that is in the middle. I am calling it r because in direct mapping it is called line, and in set-associative mapping it is called set)
EDIT:
As someone pointed out, expected and produced outcome would be helpful. I'd first like to keep the cache size, ram size, and block size constant, and only change the address.
So, given tempAddress = 27(0011011 in binary), word should be 011 (first 3 bits), r should be 011 (next 3), and set should be 0 (remaining bits).
Output is this:
tag is: 0
r is: 3
word is: 27
I've found this to be the trend if every address between 0 and 63(inclusive) that tag and r are correct, but word is equal to address.
Now, for address = 65(1000001) Expected:
tag is: 1
r is: 0
word is: 1
Output:
tag is: 1
r is: 8
word is: 65
With these ram, cache, and block sizes, to find r, I am left shifting 1 time, and right shifting 4 times. To find word, I am left shifting 4 times, then right shifting 4 times. As I understand it, when left shifting the bits on the right are filled with 0, and when right shifting an unsigned integer, the bits on the left are filled with 0. My thought was that if I left shift until I only have the bits I need, then right shift them back to the first bits, I will have the correct values. However, consistent throughout numerous addresses, after left shifting then right shifting, the places that had 1s still do. That is why word is always equal to address, because I am shifting 4 bits both left then right. And r is always equal to the 7 bits shifted right 3 times (because I go left 1 then right 4). Am I misunderstanding how bitwise shifting works?
I have an 18 bit integer that is in two's complement and I'd like to convert it to a signed number so I can better use it. On the platform I'm using, ints are 4 bytes (i.e. 32 bits). Based on this post:
Convert Raw 14 bit Two's Complement to Signed 16 bit Integer
I tried the following to convert the number:
using SomeType = uint64_t;
SomeType largeNum = 0x32020e6ed2006400;
int twosCompNum = (largeNum & 0x3FFFF);
int regularNum = (int) ((twosCompNum << 14) / 8192);
I shifted the number left 14 places to get the sign bit as the most significant bit and then divided by 8192 (in binary, it's 1 followed by 13 zeroes) to restore the magnitude (as mentioned in the post above). However, this doesn't seem to work for me. As an example, inputting 249344 gives me -25600, which prima facie doesn't seem correct. What am I doing wrong?
The almost-portable way (with assumption that negative integers are natively 2s-complement) is to simply inspect bit 17, and use that to conditionally mask in the sign bits:
constexpr SomeType sign_bits = ~SomeType{} << 18;
int regularNum = twosCompNum & 1<<17 ? twosCompNum | sign_bits : twosCompNum;
Note that this doesn't depend on the size of your int type.
The constant 8192 is wrong, it should be 16384 = (1<<14).
int regularNum = (twosCompNum << 14) / (1<<14);
With this, the answer is correct, -12800.
It is correct, because the input (unsigned) number is 249344 (0x3CE00). It has its highest bit set, so it is a negative number. We can calculate its signed value by subtracting "max unsigned value+1" from it: 0x3CE00-0x40000=-12800.
Note, that if you are on a platform, for which right signed shift does the right thing (like on x86), then you can avoid division:
int regularNum = (twosCompNum << 14) >> 14;
This version can be slightly faster (but has implementation-defined behavior), if the compiler doesn't notice that division can be exactly replaced by a shift (clang 7 notices, but gcc 8 doesn't).
Two problems: first your test input is not an 18-bit two's complement number. With n bits, two's compliment permits -(2 ^ (n - 1)) <= value < 2 ^ (n - 1). In the case of 18 bits, that's -131072 <= value < 131071. You say you input 249344 which is outside of this range and would actually be interpreted as -12800.
The second problem is that your powers of two are off. In the answer you cite, the solution offered is of the form
mBitOutput = (mBitCast)(nBitInput << (m - n)) / (1 << (m - n));
For your particular problem, you desire
int output = (nBitInput << (32 - 18)) / (1 << (32 - 18));
// or equivalent
int output = (nBitInput << 14) / 16384;
Try this out.
Write a program that reads an integer value from the keyboard into a variable of type int, and uses one of the bitwise operators (i.e. not the % operator!) to determine the positive remainder when divided by 8.
For example, 29 = (3x8)+5 and 14 = ( 2x8)+2 have positive remainder 5 and 2, respectively, when divided by 8.
I tried to search how can I solve it. What I did is to break given examples numbers into binary.
29 => 101001
8 => 001000
5 => 000101
I don't know what is operation I should do with 29 and 8 to get result 5 in binary.
While searching there's some guys said that we should do (& operation with 7 )
remainder = remainder & 7 ;
Then I tried to do this with Value itself
value = value & 7 ;
and Here's my code After doing it ...
#include <iostream>
using std::cout;
using std::endl;
using std::cin;
int main()
{
int value = 0;
int divisor = 8;
int remainder = 0;
cout << "Enter an integr and I'll divide it by 8 and give you the remainder!"
<<endl;
cin >> value;
value = value & 7;
remainder = value & divisor;
cout << remainder;
return 0;
}
It gave me result 0 when I use value 29. I don't know what I wrote was right or not.
Simply & the number itself with 7. Also, 29 = 0b11101. To generalise, the remainder when divided by a number 2 ^ n is found by &ing it with (2 ^ n) - 1 (^ == power of)
Thus, to obtain remainder modulo 16, & with 15, and so on.
Since 8 is exactly 2^3, the modulo-8 remainder of any number is composed of its last three binary digits, i. e. it equals the number bitwise-and 7:
unsigned rem8 = number & 7;
(7 is 111 in binary, that's why.)
I've seen the operators >> and << in various code that I've looked at (none of which I actually understood), but I'm just wondering what they actually do and what some practical uses of them are.
If the shifts are like x * 2 and x / 2, what is the real difference from actually using the * and / operators? Is there a performance difference?
Here is an applet where you can exercise some bit-operations, including shifting.
You have a collection of bits, and you move some of them beyond their bounds:
1111 1110 << 2
1111 1000
It is filled from the right with fresh zeros. :)
0001 1111 >> 3
0000 0011
Filled from the left. A special case is the leading 1. It often indicates a negative value - depending on the language and datatype. So often it is wanted, that if you shift right, the first bit stays as it is.
1100 1100 >> 1
1110 0110
And it is conserved over multiple shifts:
1100 1100 >> 2
1111 0011
If you don't want the first bit to be preserved, you use (in Java, Scala, C++, C as far as I know, and maybe more) a triple-sign-operator:
1100 1100 >>> 1
0110 0110
There isn't any equivalent in the other direction, because it doesn't make any sense - maybe in your very special context, but not in general.
Mathematically, a left-shift is a *=2, 2 left-shifts is a *=4 and so on. A right-shift is a /= 2 and so on.
Left bit shifting to multiply by any power of two and right bit shifting to divide by any power of two.
For example, x = x * 2; can also be written as x<<1 or x = x*8 can be written as x<<3 (since 2 to the power of 3 is 8). Similarly x = x / 2; is x>>1 and so on.
Left Shift
x = x * 2^value (normal operation)
x << value (bit-wise operation)
x = x * 16 (which is the same as 2^4)
The left shift equivalent would be x = x << 4
Right Shift
x = x / 2^value (normal arithmetic operation)
x >> value (bit-wise operation)
x = x / 8 (which is the same as 2^3)
The right shift equivalent would be x = x >> 3
Left shift: It is equal to the product of the value which has to be shifted and 2 raised to the power of number of bits to be shifted.
Example:
1 << 3
0000 0001 ---> 1
Shift by 1 bit
0000 0010 ----> 2 which is equal to 1*2^1
Shift By 2 bits
0000 0100 ----> 4 which is equal to 1*2^2
Shift by 3 bits
0000 1000 ----> 8 which is equal to 1*2^3
Right shift: It is equal to quotient of value which has to be shifted by 2 raised to the power of number of bits to be shifted.
Example:
8 >> 3
0000 1000 ---> 8 which is equal to 8/2^0
Shift by 1 bit
0000 0100 ----> 4 which is equal to 8/2^1
Shift By 2 bits
0000 0010 ----> 2 which is equal to 8/2^2
Shift by 3 bits
0000 0001 ----> 1 which is equal to 8/2^3
Left bit shifting to multiply by any power of two.
Right bit shifting to divide by any power of two.
x = x << 5; // Left shift
y = y >> 5; // Right shift
In C/C++ it can be written as,
#include <math.h>
x = x * pow(2, 5);
y = y / pow(2, 5);
The bit shift operators are more efficient as compared to the / or * operators.
In computer architecture, divide(/) or multiply(*) take more than one time unit and register to compute result, while, bit shift operator, is just one one register and one time unit computation.
Some examples:
Bit operations for example converting to and from Base64 (which is 6 bits instead of 8)
doing power of 2 operations (1 << 4 equal to 2^4 i.e. 16)
Writing more readable code when working with bits. For example, defining constants using
1 << 4 or 1 << 5 is more readable.
Yes, I think performance-wise you might find a difference as bitwise left and right shift operations can be performed with a complexity of o(1) with a huge data set.
For example, calculating the power of 2 ^ n:
int value = 1;
while (exponent<n)
{
// Print out current power of 2
value = value *2; // Equivalent machine level left shift bit wise operation
exponent++;
}
}
Similar code with a bitwise left shift operation would be like:
value = 1 << n;
Moreover, performing a bit-wise operation is like exacting a replica of user level mathematical operations (which is the final machine level instructions processed by the microcontroller and processor).
Here is an example:
#include"stdio.h"
#include"conio.h"
void main()
{
int rm, vivek;
clrscr();
printf("Enter any numbers\t(E.g., 1, 2, 5");
scanf("%d", &rm); // rm = 5(0101) << 2 (two step add zero's), so the value is 10100
printf("This left shift value%d=%d", rm, rm<<4);
printf("This right shift value%d=%d", rm, rm>>2);
getch();
}
I can not understand what this line does:
fBuffer[fByteIndex] += 1 << (fBitIndex - 1);
where:
unsigned char fBuffer[32];
int fBitIndex;
and:
for ( int i = 0; i < 32; i++ )
fBuffer[i] = 0;
fBitIndex = 8;
What << does there?
<< is the left-shift operator, and assuming fBitIndex is 8 the code
fBuffer[fByteIndex] += 1 << (fBitIndex - 1);
is equivalent to
fBuffer[fByteIndex] += 128;
Why? Because a left-shift means you shift the bits of the value "left"; in your case, 00000001 (1), is shifted left 7 times, becoming 10000000 (128).
It's called bit shifting. Each byte is composed of 8 bits (0 or 1). By shifting the bits one time to the left or the right you either multiply the number by 2 or divide it by 2.
It's a bit shift. The decimal number 1 is represented in binary (showing just the lower 8 bits) as
00000001
If I have
int i=1;
int j=i<<1;
then I'll be taking that number and shifting it one place to the left. I'll then have the binary
00000010
which in decimal is the value 2. If instead I had
int j=i<<6;
then I'd get
01000000
which in decimal would be 128.
It sets bit fBuffer[fByteIndex]
1 << N is just bit addressing.
<< is shift operator and 1<<0 is 0b1, 1<<1 is 0b10 1<<6 is 0b1000000
So based on fByteIndex and fBitIndex , propper bit is set on 1.
In this case where + is used in case that addressing bit is alredy 1, overflow occure, but I think that in your code this is not case and addresd bit is 0 before assignment.