Here is the base100million multiplier. It is slightly more complex than base10000 due to the eax register overflow, and I lapse into a short section of assembly code. It could be adapted quite easily for use with BigNum strings, and provide a 50..60X speed improvement over base10 multiplication.
uses console
function bhmMul(dword *a,*b,*c,q)
=================================
dword d,i,j,k,ca,cy,oo,oq,m100=1E8
dword aa at @a
dword bb at @b
dword cc at @c
for i=1 to q*2
aa=0 : @aa+=4 'clearing accum
next
oo=q*4-4 'shifting offset
oq=oo 'fixed offset
for i=1 to q
@cc=@c+oo 'multiplier
@bb=@b+oq 'value
@aa=@a+q*4+oo 'accum
cyy=0 'clear accum carry
cy=0 'clear multiply carry
for j=1 to q
'k=bb*cc+cy : cy=0
'if k>=m100 then
' cy=k\m100
' k=edx 'remainder after cpu division
'end if
addr edi,bb
mov eax,[edi]
addr edi,cc
mul [edi]
mov ecx,m100
div ecx
mov d,eax 'output carry
add edx,cy 'input carry
mov eax,edx 'remainder == modulus
cmp eax,ecx
(
jb exit
inc d
sub eax,ecx
)
mov k,eax
cy=d
k=k+aa+cyy : cyy=0 'accum add with carry
if k>=m100 then k-=m100 : cyy=1
aa=k
@aa-=4
@bb-=4
next
aa=cyy+cy 'final carries
oo-=4 'shift left for next line mul
next
end function
function bhmCompare(dword *b,*c,i) as int
=========================================
dword bb at @b
dword cc at @c
while i--
if bb>cc then return 1
if bb<cc then return -1
@bb+=4
@cc+=4
wend
end function
indexbase 0
int nm[32],nt[32],nr[32] 'result,target,root
/*
int nr[32],n1[32],n2[32]
'n1=14140000
'n2=14140000
'n1=22300002
'n2=22300002
'n1=87654321
'n2=2000000
bhmmul(nr,n1,n2,16)
for i=0 to 31
print i tab mid("0000000"+str(nr[i]),-8) cr
next
print cr
*/
'square roots
=============
'square root of 2
'using binary step approximator
indexbase 0
for i=0 to 31 : nr[i]=0 : next 'clear nr
nt[0]=02000000 'target value representing 2
int b,c,i
int n at @nr 'strider for square root digits
b=0x8000000 '67,108,864 shifting bit setter
i=16
while i
n or= b 'set bit
bhmMul nm,nr,nr,16
c=bhmCompare(nt,nm,16)
if c<0 then 'too large
n xor= b 'clear bit
end if
shr b 'next bit down
if b=0 then
i--
b=0x4000000
@n+=4 'next 100M down
end if
wend
'display digits in groups of eight
print "square root of 2" cr
for i=0 to 15
print i tab mid("0000000"+str(nr[i]),-8) cr
next
print cr
' 1.4142135623730950488016887242096980785696718753769480731766797379907324784621
'square root of 5 --> phi
'using binary step approximator
indexbase 0
for i=0 to 31 : nr[i]=0 : next 'clear nr
nt[0]=05000000 'target value representing 5
int b,c,i
int n at @nr 'strider for square root digits
b=0x4000000 '67,108,864 shifting bit setter
i=16
while i
n or= b 'set bit
bhmMul nm,nr,nr,16
c=bhmCompare(nt,nm,32)
if c<0 then 'too large
n xor= b 'clear bit
end if
shr b 'next bit down
if b=0 then
i--
b=0x4000000
@n+=4 'next 10k down
end if
wend
'display digits in groups of eight
print "square root of 5" cr
for i=0 to 15
print i tab mid("0000000"+str(nr[i]),-8) cr
next
'2.2360679774997896964091736687312762354406183596115257242708972454105209256378
'convert to little phi
nr[0]-=10000000 'subtract 1
'shift right 'divide by 2
addr esi,nr
mov ecx,16
clc
pushf
(
xor edx,edx
popf
(
jnc exit
mov edx,50000000
)
shr dword [esi] 'shift right carry
pushf
add [esi],edx
add esi,4
dec ecx
jg repeat
)
popf
'display digits in groups of eight
print "phi" cr
for i=0 to 15
print i tab mid("0000000"+str(nr[i]),-8) cr
next
'61803398874989484820458683436563811772030917980576286213544862270526046281890
'print 0x4000000 cr '67,108,864
'print hex 67108864
waitkey