Advertisement

adding 64-bit and 128-bit integers.

Started by June 20, 2000 07:11 PM
6 comments, last by jenova 24 years, 5 months ago
i need help performing math operations on 64-bit and 128-bits integers. fast.
To the vast majority of mankind, nothing is more agreeable than to escape the need for mental exertion... To most people, nothing is more troublesome than the effort of thinking.
How are you representing these?

Do you just need to add them, or multiply them too?

For a good time hit Alt-F4! Go ahead try it, all the cool people are doing it.
For a good time hit Alt-F4! Go ahead try it, all the cool people are doing it.
Advertisement
the numbers are to be stored as 16 bytes of contiguous memory space each. operations will include adding, subtracting, multiplying, dividing, bitwise and, or, nor, xor, comparisons, etc. pretty much everything. any suggestion would be greatly appreciated.
To the vast majority of mankind, nothing is more agreeable than to escape the need for mental exertion... To most people, nothing is more troublesome than the effort of thinking.
here some example code i just wrote.

; data declaraction.
; data stored in bit order 0..127.
__a128 dd ?, ?
__b128 dd ?, ?
__c128 dd ?, ?

; code.
mov esi, offset __a128
mov edi, offset __b128
mov ebx, offset __c128
mov dword ptr ds:[ebx], 0
mov dword ptr ds:[ebx + 4], 0
mov dword ptr ds:[ebx + 8], 0
mov dword ptr ds:[ebx + 12], 0
; bits 0 .. 31.
mov eax, dword ptr ds:[esi] ; retrieve the lo 32 bits of a.
add eax, dword ptr ds:[edi] ; retrieve the lo 32 bits of b.
jnc no_carry_lo32
; carry the one over to the next 32 bits.
mov dword ptr ds:[ebx + 4], 1
no_carry_lo32:
mov dword ptr ds:[ebx], eax ; store the lo 32 bits of c.
; bits 32 .. 63.
mov eax, dword ptr ds:[esi + 4] ; retrieve bits 32 - 63 of a.
add eax, dword ptr ds:[edi + 4] ; retrieve bits 32 - 63 of b.
jnc no_carry_lo32_to_lo63
; carry the one over to the next 32 bits.
mov dword ptr ds:[ebx + 8], 1
no_carry_lo32_to_lo63:
add dword ptr ds:[ebx + 4], eax ; add the result.
jnc no_carry_one_lo32_to_lo63
; carry the one over to the next 32 bits.
mov dword ptr ds:[ebx + 8], 1
no_carry_one_lo32_to_lo63:
; bits 64 .. 95.
mov eax, dword ptr ds:[esi + 8] ; retrieve bits 64 - 95 of a.
add eax, dword ptr ds:[edi + 8] ; retrieve bits 64 - 95 of b.
jnc no_carry_lo64_to_lo95
; carry the one over to the next 32 bits.
mov dword ptr ds:[ebx + 12], 1
no_carry_lo64_to_lo95:
add dword ptr ds:[ebx + 8], eax ; add the result.
jnc no_carry_one_lo64_to_lo95
; carry the one over to the next 32 bits.
mov dword ptr ds:[ebx + 12], 1
no_carry_one_lo64_to_lo95:
; bits 96 .. 127.
mov eax, dword ptr ds:[esi + 12] ; retrieve bits 96 - 127 of a.
add eax, dword ptr ds:[edi + 12] ; retrieve bits 96 - 127 of b.
jnc no_carry_lo96_to_lo127
; arithmetic overflow.
no_carry_lo96_to_lo127:
add dword ptr ds:[ebx + 12], eax ; add the result.
jnc no_carry_one_lo96_to_lo127
; arithmetic overflow.
no_carry_one_lo96_to_lo127:
ret


any suggestions please.
To the vast majority of mankind, nothing is more agreeable than to escape the need for mental exertion... To most people, nothing is more troublesome than the effort of thinking.
ohh yeah, the code adds two 128-bit numbers together (a, b) and stores the result in (c), and checks for arithmetic overflow.
To the vast majority of mankind, nothing is more agreeable than to escape the need for mental exertion... To most people, nothing is more troublesome than the effort of thinking.
Algorith for multiplication (a*b):

Allocate memory for bitlength(b) "very long ints", largeint array[xxx], set them all to 0.
Loop (counter runs from 0 to bitlength(b)-1):
if (b&1 == 1) array[counter] = a;
array[counter] <<= counter, check if bits are getting shifted out
b >>= 1;
endLoop

a*b = array[0] + array[1] + ......... + array[bitlength(b)-1]

Visit our homepage: www.rarebyte.de.st

GA
Visit our homepage: www.rarebyte.de.stGA
Advertisement
If you were using VC++ it has built in support of 64 bit ints with the __int64 keyword. Don''t know how it goes for speed though. If it was fast maybe you could use two of them for your 128 bit numbers. That would mean less code to type for all the operators. I think i saw a hugeint class on www.codeproject.com but it would probably not cut it speed wise.

CodeStrider.
Hey jenova, what are you doing???
Whay do you need such awful bunch of branches?
Are you aware about instruction "adc"?

__a128 dd ?, ?
__b128 dd ?, ?
__c128 dd ?, ?

mov esi, offset __a128
mov edi, offset __b128
mov ebx, offset __c128

mov eax, [esi + 0]
add eax, [edi + 0]
mov [ebx + 0], eax

mov eax, [esi + 4]
adc eax, [edi + 4]
mov [ebx + 4], eax

mov eax, [esi + 8]
adc eax, [edi + 8]
mov [ebx + 8], eax

mov eax, [esi + 12]
adc eax, [edi + 12]
mov [ebx + 12], eax

// P.S.
// btw, if you really need to catch overflow, just do it

jo _overflow


Edited by - Serge K on July 18, 2000 8:01:18 AM

This topic is closed to new replies.

Advertisement