Τετάρτη 8 Ιουλίου 2026

Long multiplication using variable base (from 2 to 36)

A long multiplication using a lambda function with closures two lists, so we do the multiplication and additions using "memory". Also carry addition performed using "memory" also (through precalculated lists). We have to produce the final lambda by passing the base for the numbers. All computations use only strings in final lambda.

function placecoma(a as string) {
  if len(a)<4 then =a :exit  
  k=StrRev$(a)
  a=""
  for i=4 to len(k) step 3
    a+=mid$(k,i-3, 3)+","
  next
  a+=mid$(k, i-3)
  a=strrev$(a)
  if left$(a,1)="," then =mid$(a,2) else =a
}
long_mul=lambda (s=10) ->{
  m=list
  ad=list
  s1=s-1
  symb="0123456789ABCDEFGHIJKLMNOPQRSTUVWXZ"
  for i=0 to s1:for j=0 to s1:
    c=i*j
    if c<s then
      m(mid(symb,i+1,1)+mid(symb,j+1,1))=mid(symb,c+1,1)
    else
      m(mid(symb,i+1,1)+mid(symb,j+1,1))=mid(symb,(c div s)+1,1)+mid(symb,(c mod s)+1,1)
    end if  
  next:next
  for i=0 to s1:for j=0 to s1:
    c=i+j
    if c<s then
      ad(mid(symb,i+1,1)+mid(symb,j+1,1))=mid(symb,c+1,1)
    else
      ad(mid(symb,i+1,1)+mid(symb,j+1,1))=mid(symb,(c div s)+1,1)+mid(symb,(c mod s)+1,1)
    end if
  next:next    
  =lambda m, ad (a as string, b as string) -> {    
    a=filter(a,",")
    b=filter(b,",")
    sign=1
    if left(a,1)="-" then sign=-1:insert 1,1 a=""
    if left(b,1)="-" then sign*=-1:insert 1,1 b=""
    ii=len(b)+1
    jj=len(a)+1
    zero=0
    acc="0"
    f=list:=0
    if a="0" then =a :exit
    for i=1 to len(b)
      bb=mid(b,ii-i,1)
      c="0"
      if not exist(f, bb) then
        dd=string$("0", len(a))
        for j=1 to len(a)
          d=m(mid(a,jj-j,1)+bb)
          if c<>"0" then
            if len(d)>1 then              
              d1=ad(right(d,1)+c)
              if len(d1)>1 then
                d2=ad(left(d,1)+left(d1,1))
                d=d2+d1
              else
                insert 2,1 d=d1
              end if
            else
              d=ad(d+c)
            end if
          end if
          c="0" :  if len(d)>1 then c=left(d,1):d=right(d,1)
          insert jj-j,1 dd=d
        next
        if c<>"0" then f(bb)=c+dd else f(bb)=dd
      end if
      if bb<>"0" then
        p1=len(f(bb))
        p=len(acc)-zero
        if p<1 then
          acc=string$("0",2-p)+acc
          p=len(acc)-zero
        end if
        c="0"
        for kk=p1 to 1
          d=""+ad(mid(acc, p,1)+mid(f(bb),kk,1))
          if c<>"0" then
            if len(d)>1 then              
              d1=ad(right(d,1)+c)
              if len(d1)>1 then
                d2=ad(left(d,1)+left(d1,1))
                d=d2+d1
              else
                insert 2,1 d=d1
              end if
            else
              d=""+ad(d+c)
            end if
          end if          
          c="0" : if len(d)>1 then c=left(d,1):d=right(d,1)
          insert p, 1 acc=d
          p-- : if p<1 and kk>1 then p=1:acc=c+acc:c="0"
        next
        if c<>"0" then
        if p<1 then acc=c+acc else insert p, 1 acc=c
        end if
      end if
      zero+=1
    next
    if sign<0 then
      ="-"+acc
    else
      =acc
    end if
  }
}
long_mul10=long_mul(10)
a="18,446,744,073,709,551,616"
print placecoma(long_mul10(a, a))="340,282,366,920,938,463,463,374,607,431,768,211,456"
print long_mul10("-832764873673674323484", "234242938742937483278432798279428")=""+(-832764873673674323484u*234242938742937483278432798279428u)
long_mul2=long_mul(2)
print long_mul2("1010101","11")="11111111"
long_mul16=long_mul(16)
print long_mul16("55","3")="FF", 0x55*0x3=0xFF


print long_mul16("55","2")="AA"
long_mul8=long_mul(8)
print long_mul8("7","2")="16"  ' 14 = 14


Δεν υπάρχουν σχόλια:

Δημοσίευση σχολίου

You can feel free to write any suggestion, or idea on the subject.