Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

__int64 on a 32-Bit machine?

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?

like image 637
koa Avatar asked Apr 22 '10 15:04

koa


People also ask

What is 32 bit and 64 bit integer?

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.

What is a 32 bit number?

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.

Are integers always 32 bit?

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.


2 Answers

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.

like image 129
Blindy Avatar answered Sep 25 '22 06:09

Blindy


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.

like image 21
AnT Avatar answered Sep 26 '22 06:09

AnT