# Bit shifts

• 05-20-2005
Buckshot
Bit shifts
I'm converting some code from Fortran to C and I've run into a problem with the random number generator convertion. It seems that when doing a bit shift in C it produces a different result than the bitshift in the Fortran. Does anyone have any ideas on how this would happen? Since the generator depends on these shifts I can't convert the code correctly if the shift is not going to work the same way.
Thanks
• 05-20-2005
Salem
Well unless you post code, it's hard to say

But shifting negative numbers right in C++ is implementation specific.
• 05-20-2005
xErath
bit shifting in C/C++ disregards the content of variables, only regards the size and the fact of not being floating point, because floating point operations are done by the co-processor
• 05-21-2005
Buckshot
Hmm, well I think I found the problem, but I don't know if it is solvable. I realized that the integers in the Fortran code are not actually 4 bytes long (as was initially told) but actually just have a precision to 9 decimal digits (-999999999 to 999999999). This would mean that any bit shift using normally declared variables in C are going to be different because of the precision. Anyt thoughts on how to get around this would be apreciated, also please note that the Fortran code cannot change.
• 05-21-2005
Salem
Well that fits nicely into 4 bytes - what's the problem?

How about posting some example results, and perhaps we can figure out what is going on
Say, in your fortran code, what does 1234 shifted 4 places left and 4 places right get you?
• 05-23-2005
Buckshot
Well, the problem doesn't present itself until you put in big numbers. Thats why I guessed that the problem was in the size of the integer. The 4 bit int does not go from -999999999 to 999999999, it has a smaller range in C++, as far as I know. Anyway, I'm using long in the C code to make sure that I'm getting 4 bit integers.
The results are here:
C++:
777755849 << 5 results in 24888187168
And the same number in Fortran shifted 5 left results in:
-881616608
• 05-23-2005
swoopy
Try using a signed int or long.
Code:

```  signed int num;   num = (signed int) 777755849 << 5;   cout << num << endl;```
• 05-23-2005
Buckshot
That worked for the first number generated, but then:
C++:
ix = -9054424
ix = 9054354
The first number is the initial then the second is shifted 17 to the right
and Fortran:
ix = -9054424
ix = -9066350
under the same calculation

Also, I forgot to say the exact calculation includes an exclusive or, the reason I left this out was because I determined the problem with the calculation was with the shift. The calculation is this:
Code:

`ix = ix ^ (ix >> 17);`
• 05-23-2005
Dave_Sinkula
Code:

```#include <iostream> void foo(int ix) {   std::cout << "foo: ix = " << ix << std::endl;   std::cout << "foo: ix >> 17 = " << (ix >> 17) << std::endl;   ix = ix ^ (ix >> 17);   std::cout << "foo: ix = " << ix << std::endl; } void bar(int ix) {   std::cout << "bar: ix = " << ix << std::endl;   std::cout << "bar: (unsigned)ix >> 17 = " << ((unsigned)ix >> 17) << std::endl;   ix = ix ^ ((unsigned)ix >> 17);   std::cout << "bar: ix = " << ix << std::endl; } int main() {   foo(-9054424);   bar(-9054424);   return 0; } /* my output foo: ix = -9054424 foo: ix >> 17 = -70 foo: ix = 9054354 bar: ix = -9054424 bar: (unsigned)ix >> 17 = 32698 bar: ix = -9066350 */```
• 05-23-2005
swoopy
Confirming what Dave posted, it looks like you need to cast to unsigned int before you do any shift operation:
Code:

`  num = num ^ static_cast<unsigned int>(num) >> 17;`
Which is the opposite of what I posted before. :D
• 05-23-2005
Buckshot
The Fortran bit shifts eventually loops to zero and so the Fortran after shifting to the left enough will get to zero and stop. The C++ shift however will keep looping (it will go to 1, and then keep going). So does anyone know how to make the C not go to one (for example, a different shift command)
• 05-23-2005
swoopy
Perhaps you should post some code, because as long as you cast to unsigned it should go to 0. For example:
Code:

```#include <iostream> #include <climits> using namespace std; int main() {   int num = 0x1;   cout << hex << num << dec << endl;   for (int i=0; i<sizeof(int)*CHAR_BIT; ++i)   {       num = static_cast<unsigned int>(num) << 1;       cout << hex << num << dec << endl;   } }```
• 05-23-2005
DougDbug
Quote:

...random number generator convertion.
If you're simply trying to generate a random number, it's easy in C/C++. You can use the standard rand() function. And, here's the cprogramming.com tutorial.

Playing around with bits is always fun, but it can be tricky in C/C++ because an integer can be 16, 32, or even 64 bits depending on the system.
• 05-23-2005
okinrus
Quote:

Hmm, well I think I found the problem, but I don't know if it is solvable. I realized that the integers in the Fortran code are not actually 4 bytes long (as was initially told) but actually just have a precision to 9 decimal digits (-999999999 to 999999999). This would mean that any bit shift using normally declared variables in C are going to be different because of the precision. Anyt thoughts on how to get around this would be apreciated, also please note that the Fortran code cannot change.
You can get larger range in C++ by using 64 bits. But how are you determining this precison? I wouldn't trust the Fortran write routines. You should also look at an assembly listing or manual to find the exact shifting and types the Fortran compiler is using.