I just tried something in MSVC 2010 on my 32-bit machine here and found out that I can use __int64
in my programs - which actually work!
How is that possible?
A 32 bit Signed Integer can house a number from −2,147,483,648 to 2,147,483,647 Unsigned: 0 to 4,294,967,295. A 64 bit Signed Integer can house a number from −9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 Unsigned: 0 to 18,446,744,073,709,551,615.
32-bit, in computer systems, refers to the number of bits that can be transmitted or processed in parallel. In other words, 32-bits the number of bits that compose a data element. For a data bus, 32-bit means the number of pathways available, meaning that it has 32 pathways in parallel for data to travel.
int is always 32 bits wide. sizeof(T) represents the number of 8-bit bytes (octets) needed to store a variable of type T . (This is false because if say char is 32 bits, then sizeof(T) measures in 32-bit words.) We can use int everywhere in a program and ignore nuanced types like size_t , uint32_t , etc.
Same way 32-bit arithmetic worked on 16-bit systems.
In this case, it uses 2 32-bit memory addresses to form a 64-bit number together. Addition/substraction is easy, you do it by parts, the only gotcha is taking the carry-over from the lower part to the higher part. For multiplication/division, it's harder (ie more instructions).
It's obviously slow, quite a bit slower than 32 bit arithmetic for multiplication, but if you need it, it's there for you. And when you upgrade to a 64-bit processor compiler, it gets automatically optimized to one instruction with the bigger word size.
The Visual Studio 2010 Professional implementation of 64 bit multiplication on a 32-bit processor, compiled in release mode, is:
_allmul PROC NEAR A EQU [esp + 4] ; stack address of a B EQU [esp + 12] ; stack address of b mov eax,HIWORD(A) mov ecx,HIWORD(B) or ecx,eax ;test for both hiwords zero. mov ecx,LOWORD(B) jnz short hard ;both are zero, just mult ALO and BLO mov eax,LOWORD(A) mul ecx ret 16 ; callee restores the stack hard: push ebx A2 EQU [esp + 8] ; stack address of a B2 EQU [esp + 16] ; stack address of b mul ecx ;eax has AHI, ecx has BLO, so AHI * BLO mov ebx,eax ;save result mov eax,LOWORD(A2) mul dword ptr HIWORD(B2) ;ALO * BHI add ebx,eax ;ebx = ((ALO * BHI) + (AHI * BLO)) mov eax,LOWORD(A2) ;ecx = BLO mul ecx ;so edx:eax = ALO*BLO add edx,ebx ;now edx has all the LO*HI stuff pop ebx ret 16 ; callee restores the stack
As you can see, it's a LOT slower than normal multiplication.
Why do you find it surprising? There's nothing to prevent the compiler from supporting 64-, 128- or more-bit integer types on a 32-bit machine. The compiler can even support 57- and 91-bit types, if it feels like it. In practice supporting 2N-bit integer arithmetic on an N-bit machine is a relatively easy task, since the instruction set of a typical machine is often designed with this kind of functionality in mind.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With