my compiler keeps giving me errors when I try to left shift (<<) past 32 bits in what the visual c++ compiler is telling me is a 64 bit integer (type long long). Is there any way I can do this, or do I need to take an alternate approach?
Printable View
my compiler keeps giving me errors when I try to left shift (<<) past 32 bits in what the visual c++ compiler is telling me is a 64 bit integer (type long long). Is there any way I can do this, or do I need to take an alternate approach?
Something more descriptive than "giving me errors" would be useful, like for example actual code and actual error messages.
This for example, works fine for me.
Code:#include <stdio.h>
#include <stdlib.h>
int main ( ) {
__int64 i = 1;
i <<= 33;
printf("%I64x\n", i );
return 0;
}
$ cl /nologo foo.c
foo.c
$ foo.exe
200000000
Not sure what you're trying to do, but this works for me:
[Edit: beaten to it by Salem]Code:#include <iostream>
#include <iomanip>
int main() {
__int64 x = 1;
int i;
for(i = 0; i < 64; i += 5) {
std::cout << i << " " << std::hex << (x << i) << std::endl;
}
}
Output:
0 1
5 20
10 400
15 8000
20 100000
25 2000000
30 40000000
35 800000000
40 10000000000
45 200000000000
50 4000000000000
55 80000000000000
60 1000000000000000
--
Mats
ah I just realized my error, I was doing this:
instead of this:Code:#include <iostream>
using namespace std;
void main() {
__int64 a (0);
a ^= 1<<33;
cout << a << endl;
}
Code:#include <iostream>
using namespace std;
void main() {
__int64 a (1), shift (1);
a ^= shift<<33;
cout << a << endl;
}
it was giving me an undefined behavior error, but now I realize the 'a' variable wasn't the problem, it was the constant '1<<33'. Thanks for the help!
thanks Mats
Sorry to hijack a finished thread, but what range of operations do 32-bit chips support on 64-bit integers?
Most 32-bit chips don't support 64-bit integers natively, but there are ways to support 64-bit operations as multiple operations, and some special operations to "extend to 64-bit", such as divide of two 64-bit numbers into a 32-bit number, and a multiply of two 32-bit that becomes a 64-bit number. Most recent compilers support 64-bit for all binary and unary operators +, -, *, /, %, &, |, ^, ~ and !.
It is really up to the compiler to fill in the blanks here. You can really build "infinite" integers using the range of instructions supported by the processor. A 128-bit addition would look like this:
The instruction adc is "add with carry", where the carry-over from the previous calculation is carried from one calculation to the next - just like if you add 8 + 4, you get 2 and 1 in "carry", then add the carry to "nothing" gives 12.Code:mov eax,[a] // low 32-bit
add [b], eax
mov eax, [a+4] // Next 32-bit
adc [b+4], eax
mov eax, [a+8] // Next 32-bit
adc [b+8], eax
mov eax, [a+12] // Next 32-bit
adc [b+12], eax
A similar principle can be used for subtract and shift operatrons. Logical operations don't even need a carry. Multiply and divide are a bit tricky, but far from impossible (it just takes a lot longer than doing it in hardware if it's not a "simple" operation).
--
Mats
Right! In the old days of DOS & 16-bit Windows, running on 16-bit x86 processors, you could run C/C++ which requires 32 bits for a type long. There are 8-bit machines that run C/C++.Quote:
It is really up to the compiler to fill in the blanks here.