RealBigMath in Development (Unfinished Source Released)

Everything else that doesn't fall into one of the other PB categories.
Booger
Enthusiast
Enthusiast
Posts: 134
Joined: Tue Sep 04, 2007 2:18 pm

RealBigMath in Development (Unfinished Source Released)

Post by Booger »

Hello all, I am currently developing a Big math Lib for cryptography (RSA) and such large prime number playing. It is needed for Https in my web server.

Any error checking or crash testing is welcome.
And the lib will be released to community when done.

Current Commands open for testing are:

RealAddI-Add Integers up to 18000 digits for now (Supports Signs)
RealFastAddI- Fast add, No Sign Support. 18000 digits
RealAddF-Add floats up to 9000 digits on each side of decimal. (No sign support yet)
RealSubI-Subtract Integers up to 18000 for now (Supports Signs)

The Lib is written in PureBasic, but is not compiled as thread safe yet.

Simple Test Skeleton:

Code: Select all

RealMathInit()
OpenConsole()
timer = ElapsedMilliseconds()

String2.s = "0" : String1.s = ".12345678901234567890123456789"
For a = 1 To 10203
  answer.s = RealAddI(string2, string1)
  string2 = answer
  ;string1 = answer
  ; PrintN("Answer=  " + string2)
Next
PrintN("Answer=  " + string2)
PrintN("time taken was " + StrF((ElapsedMilliseconds()-timer)/1000) + " Seconds")
Input()
End
New Test Lib here:
http://rapidshare.com/files/227382489/RealBigMath.html

InstallDirectory\PureLibraries\UserLibraries

Restart compiler.

Thanks
Last edited by Booger on Sat Oct 24, 2009 3:13 pm, edited 2 times in total.
User avatar
Michael Vogel
Addict
Addict
Posts: 2797
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Post by Michael Vogel »

Will be interesting for me, I will have a look at that :wink:

Maybe you want also to have a look at some code done already some years ago - I wrote some very fast integer math routines (Code

Michael
Booger
Enthusiast
Enthusiast
Posts: 134
Joined: Tue Sep 04, 2007 2:18 pm

Post by Booger »

Very Nice Code. Innovative. Complex.
I read that very thread looking for fast big math. Don't know how I missed your code block.


Currently running benchmarks for calculating 10,000 powers of 2

Yours=18.9
mine=5.6

Please note I don't support Negative yet until I get Subtract in the works.

Then it would be a fair benchmark (checking for signs).


Perhaps you would like to work on the Lib?

I have a SVN with room for 2 Members, if you are interested.
User avatar
Michael Vogel
Addict
Addict
Posts: 2797
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Post by Michael Vogel »

Booger wrote:[...]Currently running benchmarks for calculating 10,000 powers of 2[...]
My actual code looks something like this (most important parts)...

Code: Select all

Declare VNFCopy(*a.VNF,*b.VNF);	b = a
Declare VNFMul(*a.VNF,*b.VNF,*c.VNF);  	c = a*b
Declare VNFSqr(*a.VNF);		a = a*a
Declare VNFPow(*a.VNF,b.l,*c.VNF); 	c = a^b

Procedure VNFCopy(*a.VNF,*b.VNF)
	Protected n

	n=*a\len
	*b\len=n
	*b\sign=*a\sign

	While n>=0
		*b\num[n]=*a\num[n]
		n-1
	Wend

EndProcedure

Procedure VNFMul(*a.VNF,*b.VNF,*c.VNF)

	Protected la
	Protected lb
	Protected n

	Protected s.q
	Protected z.q

	If (*a\len<0) Or (*b\len<0)
		VNFError(*a\len,*b\len,*c.VNF)
	Else
		*c\sign=(*a\sign + *b\sign)&1;	because #VNFNegative=1
		*c\len=*a\len+*b\len+1
		For n=0 To *c\len
			*c\num[n]=0
		Next n

		la=0
		Repeat
			lb=0
			z=*b\num[lb]
			Repeat
				s=*a\num[la] * *b\num[lb] + *c\num[la+lb]
				*c\num[la+lb]=s%#VNFMod
				*c\num[la+lb+1]+s/#VNFMod
				lb+1
			Until lb>*b\len
			la+1
		Until la>*a\len

		VNFNormalize(*c)

	EndIf
EndProcedure
Procedure VNFSqr(*a.VNF)
	If *a\len>=0
		VNFMul(*a,*a,VNF_Cache_C)
		VNFCopy(VNF_Cache_C,*a)
	EndIf
EndProcedure

Procedure VNFPow(*a.VNF,b.l,*c.VNF)

	Protected z=0,s,sign

	If b<0

		; a^b | b<0 not implemented for now...
		VNFError(#VNFNotImplemented,0,*c.VNF)

	ElseIf *a\len>=0

		VNFCopy(*a,VNF_Cache_A)
		PutNumber(@"1",VNF_Cache_B)

		If VNFPositive(*a)=#False
			VNFAbs(VNF_Cache_A)
			If b&1 : VNF_Cache_B\Sign=#VNFNegative : EndIf
		EndIf

		While b>0
			s=1<<z
			If b&s
				VNFMul(VNF_Cache_A,VNF_Cache_B,VNF_Cache_C)
				VNFCopy(VNF_Cache_C,VNF_Cache_B)
				b-s
			EndIf

			If b
				VNFSqr(VNF_Cache_A)
				z+1
			EndIf

		Wend

		VNFCopy(VNF_Cache_B,*c)

	EndIf
EndProcedure

Code: Select all

PutNumber(@"2",x)
VNFPow(x,10000,z)
Debug "2^10000="+Number(z)
Booger wrote:[...]Perhaps you would like to work on the Lib?[...]
Would be interesting, but actually I'm overloaded - I'll try to keep an eye on this thread and your work :wink:

Michael[/code]
Booger
Enthusiast
Enthusiast
Posts: 134
Joined: Tue Sep 04, 2007 2:18 pm

Post by Booger »

Updated Lib in first post.

Added RealSubI, RealFastAddI

Added Sign Support for RealAddI

Thanks.
User avatar
pdwyer
Addict
Addict
Posts: 2813
Joined: Tue May 08, 2007 1:27 pm
Location: Chiba, Japan

Post by pdwyer »

Could you compile these as DLLs too (I assume that you don't want to release the code for a PBI - which is fine)

Libs would be great in a perfect world but they tend to have issues between compiler versions and I don't want to be a part of that pain if I can't get in a fix it myself.

I have some of these functions in code posted in the tips section too, and am interested in helping test. my code wasn't all that fast and would be a little painful for RSA needs. I'm happy to put some effort into helping something better into existance
Paul Dwyer

“In nature, it’s not the strongest nor the most intelligent who survives. It’s the most adaptable to change” - Charles Darwin
“If you can't explain it to a six-year old you really don't understand it yourself.” - Albert Einstein
Booger
Enthusiast
Enthusiast
Posts: 134
Joined: Tue Sep 04, 2007 2:18 pm

Post by Booger »

I will more than likely release the source after the code is proven effective and accurate. Being that it is so complex I would rather bugs to pop up(if any) with unmodified code, as such, this is a lib for testing.

You are welcome to work on the Lib if you wish, though it is quite a mess inventing new ways to do math and such. But be forewarned, I am a severe cycle counter in this code and is still full of experiments commented out.

No internal Procedure calls to avoid stack overhead, and a Goto here and there to save a few processor cycles. The Goto's are not planned to stay in the code unless they prove to be the only way to save the cycles.

So, if you are interested, PM me with your email, and I will send you an invitation to the SVN so you can get the code.

Thanks.
Booger
Enthusiast
Enthusiast
Posts: 134
Joined: Tue Sep 04, 2007 2:18 pm

Re: RealBigMath in Development (Testers needed)

Post by Booger »

I have been very busy all summer. And coming back to work on this code I have not gotten much further than breaking it.
Here I leave the original unbroken code for the forum so others may have their way with it. Full development comments and experiments included.
Please note, it is not finished, there are globals and such other bad practices :shock: .
All I ask, is if you improve, please post your improvement(s) here :D .

Code: Select all

;****************************************************************************
;TAILBITE TO COMPILE
;OR REMOVE LIB FROM USER LIB DIRECTORY TO MAKE DLL

ProcedureDLL RealMathInit()
  Global Dim wholeNumber1.q(1000)
  Global Dim wholeNumber2.q(1000)
  Global Dim PartialProduct.q(1000)
  ;Global Dim Percent1.q(1000)
  ;Global Dim Percent2.q(1000)
  Global Dim WholeNumberCarry(1000)
  Global Temp.s = Space(1000)
  ;Global Result.s=Space(18000)
  ;#Pattern18 = "0000000000000000000";One Extra here to leave room for Null character
  ;#Pattern9 = "000000000"
  Global *ScratchBuffer = AllocateMemory(1000)
  Global Dim MultiplyAdd.s(2000)
  ;Global Dim PowersOfTwo.q(60000,1000)
  Global Dim PartialProductTemp.q(1000)
EndProcedure
Declare.s RealAddI(string1.s, string2.s)

; Procedure.l STRLen(*pString)
;   MOV eax, *pString
;
;   !pxor mm1, mm1
;   !MOV ecx, eax
;   !MOV edx, eax
;   !AND ecx, -8
;   !AND eax, 7
;   !movq mm0, [ecx]
;   !por mm0, [l_stringtbl+eax*8]
;   !@@:
;   !ADD ecx, 8
;   !pcmpeqb mm0, mm1
;   !packsswb mm0, mm0
;   !movd eax, mm0
;   !movq mm0, [ecx]
;   !TEST eax, eax
;   !JZ @b
;
;   !BSF eax, eax
;   !SHR eax, 2
;   !LEA ecx, [ecx+eax-8]
;   !SUB ecx, edx
;   !MOV eax, ecx
;
;   !emms
;   ProcedureReturn
; EndProcedure
; Macro Len(string)
;   ; STRLen(@String)
;   MemoryStringLength(@string)
; EndMacro

; Macro RMerge18(string)
;   ;   StringTemp.s = #Pattern18
;   ;   PokeS(@stringTemp + (18-Len(string)))
;   ;   @String = @StringTemp
;   Merge18R(String)
; EndMacro
Macro Mid(string, start, length)
  ;MidMem(@string, start, length)
  PeekS(@string + (Start-1), length)
EndMacro
; Procedure.s Merge18R(string.s);Internal: Gay, not faster
;   PokeS(*ScratchBuffer, #Pattern18)
;   PokeS(*ScratchBuffer + (18-Len(string)), string)
;   ;String = @StringTemp
;   ProcedureReturn PeekS(*ScratchBuffer)
; EndProcedure

ProcedureDLL.s RealABS(String1.s);RealAbs (Number)
  
  Result.s = "Sorry, Not Implemented Yet."
  
  ProcedureReturn Result.s
EndProcedure
ProcedureDLL.s RealInt(String1.s);RealInt (Number)
  
  Result.s = "Sorry, Not Implemented Yet."
  
  ProcedureReturn Result.s
  
EndProcedure
ProcedureDLL.s RealSubI(String1.s, String2.s);Sign Support
  result.s = ""
  ;   PrintN(string1)
  ;   PrintN(string2)
  WholeNumberLen1 = Len(String1)
  WholeNumberLen2 = Len(String2)
  If Mid(String1, 1, 1) = "-"
    WholeNumberNegative1 = #True
    string1 = Mid(string1, 2, WholeNumberLen1);Remove Sign
    WholeNumberLen1-1
  Else
    WholeNumberNegative1 = #False
  EndIf
  If Mid(String2, 1, 1) = "-"
    WholeNumberNegative2 = #True
    string2 = Mid(string2, 2, WholeNumberLen2);Remove Sign
    WholeNumberLen2-1
  Else
    WholeNumberNegative2 = #False
  EndIf
  ;   PrintN(string1)
  ;   PrintN(string2)
  ;(++)= Subtract small from Big, sign takes Biggest***************************************************
  ;(--)= Subtract small from Big, sign Positive***************************************************
  ;Should Pass by the next checks!!!!!*****************************************************************
  
  WholeNumberSize1 = WholeNumberLen1/18
  WholeNumberRemainder1 = WholeNumberLen1%18
  WholeNumberSize2 = WholeNumberLen2/18
  WholeNumberRemainder2 = WholeNumberLen2%18
  
  ;*******************************************************************
  ;Clean up from previous call
  ;*******************************************************************
  result.s = ""
  If WholeNumberSize1>WholeNumberSize2
    count = WholeNumberSize1 + 1;Number of Registers to Subtract
    For z = 1 To count
      WholeNumber2(z) = 0;Clear Out Unused Registers this session
      WholeNumberCarry(z) = 0;Clear out Carry Flags
    Next
  Else
    count = WholeNumberSize2 + 1;Number of Registers to SubTract
    For z = 1 To count
      WholeNumber1(z) = 0;Clear Out Unused Registers this session
      WholeNumberCarry(z) = 0;Clear Out Carry Flags
    Next
  EndIf
  ;********************************************************************
  ;Get Large Numbers out of Strings in 18 char chunks for Quad Math
  ;********************************************************************
  For z = 1 To WholeNumberSize1
    WholeNumber1(z) = Val(Mid(string1, (WholeNumberLen1-(z*18)) + 1, 18));????Len+1 why? Needs fixed
  Next
  WholeNumber1(z) = Val(Mid(string1, 1, WholeNumberRemainder1));Here Z is already incremented by the For Loop on Exit
  For z = 1 To WholeNumberSize2
    WholeNumber2(z) = Val(Mid(string2, (WholeNumberLen2-(z*18)) + 1, 18));????Len+1 why? Needs fixed
  Next
  WholeNumber2(z) = Val(Mid(string2, 1, WholeNumberRemainder2));Here Z is already incremented by the For Loop on Exit
  ;*******************************************************************
  ;Now we must Do String Size Compare--Cycle eater right here :)
  ;*******************************************************************
  If WholeNumberLen2<WholeNumberLen1
    Compare = #False
    
  ElseIf WholeNumberLen2>WholeNumberLen1
    
    Compare = #True
  Else
    For z = count To 1 Step -1
      PrintN(Str(wholeNumber1(z)))
      PrintN(Str(wholeNumber2(z)))
      If WholeNumber2(z)>WholeNumber1(z)
        PrintN(string1)
        PrintN(string2)
        PrintN(Str(wholeNumber1(z)))
        PrintN(Str(wholeNumber2(z)))
        Compare = #True
        Break
        ;EndIf
      Else
        Compare = #False
        Break
      EndIf
      
    Next
  EndIf
  
  ;PrintN("Compare=" + Str(compare))
  ;(-+)=add  String 2 Answer is Negative***************************************************
  If WholeNumberNegative1 And Not WholeNumberNegative2; if this is true, Biggest Number Sets Sign
    ;string1 = Mid(string1, 2, WholeNumberLen1);Remove Sign
    ;If compare = #False
    result = "-"
    ;EndIf
    
    ;PrintN("(-+)")
    Goto SubAdd
    ;ProcedureReturn result + RealAddI(string1, String2);result;RealAddI("123", String2);result.s
    
  EndIf
  ;(+-)=add opposite String 2 sign is positive***************************************************
  If WholeNumberNegative2 And Not WholeNumberNegative1;if this is true, Positve -(-)=+
    
    ;PrintN("(+-)")
    Goto SubAdd
    ;ProcedureReturn RealAddI(string1, String2)
  EndIf
  
  ;(--)= Subtract small from Big, Biggest takes sign***************************************************
  If wholeNumberNegative1 And wholeNumberNegative2
    If compare = #True;string2>string1
      
      result = ""
      ;       PrintN(string2)
      ;       PrintN(string1)
      ;       PrintN("(--)")
      Goto String2IsBigger
    Else
      result = "-"
      ;PrintN("(--)")
      Goto String1IsBigger
    EndIf
  ElseIf wholeNumberNegative1 = #False And wholeNumberNegative2 = #False
    If compare = #True;string2>string1
      
      result = "-"
      ;PrintN("(++)")
      Goto String2IsBigger
    EndIf
  ElseIf compare = #True And wholeNumberNegative2;string2>string1
    result = "-"
    
    Goto String2IsBigger
  ElseIf compare = #False And WholeNumberNegative1;String1>String2
    result = "-"
  EndIf
  ;PrintN(result)
  
  String1IsBigger:
  For z = 1 To count
    If WholeNumber1(z)<WholeNumber2(z);Borrow
      ;temp.s = Str(WholeNumber2(z))
      WholeNumber1(z) + 1000000000000000000 ;! 1000000000000000000;Val(LSet("1", Len(temp) + 1, "0"))
      ;If z< = count-1
      wholeNumber1(z + 1)-1;000000000000000000;Val(LSet("1", Len(temp) +1, "0"));1000000000000000000 ;! 1000000000000000000= -wholeNumber1(z + 1)
      ; EndIf
      ;PrintN(Str(Val(LSet("1", Len(temp) + 1, "0"))))
      ;       If wholeNumber1(z + 1)<0
      ;
      ;       EndIf
    EndIf
    WholeNumber1(z) = WholeNumber1(z)-WholeNumber2(z) ;+ WholeNumberCarry(z)
    ;     If wholeNumber1(z)<0
    ;       wholeNumber1(z)=-WholeNumber1(z)
    ;     EndIf
  Next
  If WholeNumber1(count)<-999999999999999999
    wholeNumber1(count) + 1000000000000000000
  EndIf
  Goto SubtractionEnd
  String2IsBigger:
  ;Goto String1IsBigger
  For z = 1 To count
    If WholeNumber1(z)>WholeNumber2(z)
      ;temp.s = Str(WholeNumber1(z))
      WholeNumber2(z) + 1000000000000000000;Val(LSet("1", Len(temp) + 1, "0"));1000000000000000000 ;! 1000000000000000000;
      ;If z<=count-1
      wholeNumber2(z + 1)-1;0000000000000000000;Val(LSet("1", Len(temp) -1, "0"));1000000000000000000 ;! 1000000000000000000= -wholeNumber1(z + 1)
      ;EndIf
      ;PrintN("String2")
      PrintN(Str(Val(LSet("1", Len(temp) + 1, "0"))))
      ;     If WholeNumber2(z)<WholeNumber1(z);Borrow
      ;       WholeNumber2(z) + 1000000000000000000 ! 1000000000000000000;
      ;       wholeNumber2(z + 1)-1000000000000000000
      ;     EndIf
    EndIf
    WholeNumber1(z) = WholeNumber2(z)-WholeNumber1(z) ;+ WholeNumberCarry(z)
    
  Next
  If WholeNumber1(count)<-999999999999999999
    wholeNumber1(count) + 1000000000000000000
  EndIf
  
  SubtractionEnd:
  If WholeNumber1(count) = 0 ;Or
    result + Str(WholeNumber1(count-1))
    For z = count-2 To 1 Step -1
      If WholeNumber1(z)<0
        WholeNumber1(z) = -WholeNumber1(z)
      EndIf
      ;temp=Str(WholeNumber1(z))
      result + RSet(Str(WholeNumber1(z)), 18, "0");Merge18r(Str(WholeNumber1(z)));Merge18r(temp);RSet(Str(WholeNumber1(z)), 18, "0");RMerge18(Str(WholeNumber1(z)))
    Next
  Else
    result + Str(WholeNumber1(count))
    For z = count-1 To 1 Step -1
      If WholeNumber1(z)<0
        WholeNumber1(z) = -WholeNumber1(z);Make sure Negative sign dont show in result until the end
      EndIf
      ;temp = Str(WholeNumber1(z))
      result + RSet(Str(WholeNumber1(z)), 18, "0");Merge18r(Str(WholeNumber1(z)));Merge18r(temp);RSet(Str(WholeNumber1(z)), 18, "0")
    Next
  EndIf
  ProcedureReturn result
  SubAdd:
  For z = 1 To count
    WholeNumber1(z) = WholeNumber1(z) + WholeNumber2(z); + WholeNumberCarry(z)
    If WholeNumber1(z)>999999999999999999
      WholeNumber1(z + 1) + 1 ;WholeNumberCarry(z + 1) = 1
      WholeNumber1(z)-1000000000000000000
    EndIf
  Next
  ;Goto SubAddEnd
  SubAddEnd:
  If WholeNumber1(count) = 0
    result + Str(WholeNumber1(count-1))
    For z = count-2 To 1 Step -1
      ;temp=Str(WholeNumber1(z))
      result + RSet(Str(WholeNumber1(z)), 18, "0");Merge18r(Str(WholeNumber1(z)));Merge18r(temp);RSet(Str(WholeNumber1(z)), 18, "0");RMerge18(Str(WholeNumber1(z)))
    Next
  Else
    result + Str(WholeNumber1(count))
    For z = count-1 To 1 Step -1
      ;temp = Str(WholeNumber1(z))
      result + RSet(Str(WholeNumber1(z)), 18, "0");Merge18r(Str(WholeNumber1(z)));Merge18r(temp);RSet(Str(WholeNumber1(z)), 18, "0")
    Next
  EndIf
  ProcedureReturn result
EndProcedure

ProcedureDLL.s RealSubF(String1.s, String2.s)
  
  Result.s = "Sorry, Not Implemented Yet."
  
  ProcedureReturn Result.s
  
EndProcedure
ProcedureDLL.s RealAddF(String1.s, String2.s);RealAddF (Float1,Float2) No Sign Support Yet
  ;   Result.s = "Sorry, Not Implemented Yet."
  ;
  ;   ProcedureReturn Result.s
  WholeNumberLen1 = Len(String1)
  WholeNumberLen2 = Len(String2)
  DecimalPoint1 = FindString(String1, ".", 0)
  DecimalPoint2 = FindString(String2, ".", 0)
  temp1.s = Mid(string1, DecimalPoint1 + 1, WholeNumberLen1)
  PercentStringLen1 = Len(temp1);We Need percent Len to pad for addition
  temp2.s = Mid(string2, DecimalPoint2 + 1, WholeNumberLen2)
  PercentStringLen2 = Len(temp2);We Need percent Len to pad for addition
  DecimalPoint = WholeNumberLen1-DecimalPoint1;we do this in case both lens are equal; needs optimized to cut out cycles
  If PercentStringLen1>PercentStringLen2
    temp2 = LSet(temp2, PercentStringLen1, "0");  We pad, Dont for get to change Len!
    DecimalPoint = WholeNumberLen1-DecimalPoint1;set where we stick the decimal after adding
    wholeNumberLen2 + Len(temp2)-PercentStringLen2;change Len
  EndIf
  If PercentStringLen2>PercentStringLen1
    Temp1 = LSet(Temp1, PercentStringLen2, "0");  We pad, Dont for get to change Len!
    DecimalPoint = WholeNumberLen2-DecimalPoint2;set where we stick the decimal after adding
    wholeNumberLen1 + Len(temp1)-PercentStringLen1;change Len
  EndIf
  
  string1 = Mid(string1, 1, DecimalPoint1-1) + temp1;Strip out Decimal Point so We can Add Like Normal
  WholeNumberLen1-1;Len=Len-1 now because we took out Decimal Point
  
  string2 = Mid(string2, 1, DecimalPoint2-1) + temp2;Strip out Decimal Point so We can Add Like Normal
  WholeNumberLen2-1;Len=Len-1 now because we took out Decimal Point
  
  WholeNumberSize1 = WholeNumberLen1/18
  WholeNumberRemainder1 = WholeNumberLen1%18
  WholeNumberSize2 = WholeNumberLen2/18
  WholeNumberRemainder2 = WholeNumberLen2%18
  
  ;*******************************************************************
  ;Clean up from previous call
  ;*******************************************************************
  result.s = ""
  If WholeNumberSize1>WholeNumberSize2
    count = WholeNumberSize1 + 1;Number of Registers to Add
    For z = 1 To count
      WholeNumber2(z) = 0;Clear Out Unused Registers this session
      WholeNumberCarry(z) = 0;Clear out Carry Flags
    Next
  Else
    count = WholeNumberSize2 + 1;Number of Registers to Add
    For z = 1 To count
      WholeNumber1(z) = 0;Clear Out Unused Registers this session
      WholeNumberCarry(z) = 0;Clear Out Carry Flags
    Next
  EndIf
  
  For z = 1 To WholeNumberSize1
    WholeNumber1(z) = Val(Mid(string1, (WholeNumberLen1-(z*18)) + 1, 18));????Len+1 why? Needs fixed
  Next
  
  WholeNumber1(z) = Val(Mid(string1, 1, WholeNumberRemainder1));Here Z is already incremented by the For Loop on Exit
  
  For z = 1 To WholeNumberSize2
    WholeNumber2(z) = Val(Mid(string2, (WholeNumberLen2-(z*18)) + 1, 18));????Len+1 why? Needs fixed
  Next
  WholeNumber2(z) = Val(Mid(string2, 1, WholeNumberRemainder2));Here Z is already incremented by the For Loop on Exit
  
  For z = 1 To count
    WholeNumber1(z) = WholeNumber1(z) + WholeNumber2(z) + WholeNumberCarry(z)
    If WholeNumber1(z)>999999999999999999;there was a carry
      WholeNumberCarry(z + 1) = 1;set carry on next register add
      WholeNumber1(z)-1000000000000000000;remove the carry from this register
    EndIf
  Next
  
  If WholeNumber1(count) = 0
    result + Str(WholeNumber1(count-1))
    For z = count-2 To 1 Step -1
      ;temp=Str(WholeNumber1(z))
      result + RSet(Str(WholeNumber1(z)), 18, "0");Merge18r(Str(WholeNumber1(z)));Merge18r(temp);RSet(Str(WholeNumber1(z)), 18, "0");RMerge18(Str(WholeNumber1(z)))
    Next
  Else
    result + Str(WholeNumber1(count))
    For z = count-1 To 1 Step -1
      ;temp = Str(WholeNumber1(z))
      result + RSet(Str(WholeNumber1(z)), 18, "0");Merge18r(Str(WholeNumber1(z)));Merge18r(temp);RSet(Str(WholeNumber1(z)), 18, "0")
    Next
  EndIf
  ProcedureReturn Mid(result, 1, Len(result)-DecimalPoint) + "." + Mid(result, Len(result)-DecimalPoint + 1, Len(result));result
  
EndProcedure
ProcedureDLL.s RealAddI(String1.s, String2.s);RealAddI (Integer1,Integer2) Sign Supported
  WholeNumberLen1 = Len(String1)
  WholeNumberLen2 = Len(String2)
  If Mid(String1, 1, 1) = "-"
    WholeNumberNegative1 = #True
    string1 = Mid(string1, 2, WholeNumberLen1);Remove Sign
    WholeNumberLen1-1
  Else
    WholeNumberNegative1 = #False
  EndIf
  If Mid(String2, 1, 1) = "-"
    WholeNumberNegative2 = #True
    string2 = Mid(string2, 2, WholeNumberLen2);Remove Sign
    WholeNumberLen2-1
  Else
    WholeNumberNegative2 = #False
  EndIf
  
  WholeNumberSize1 = WholeNumberLen1/18
  WholeNumberRemainder1 = WholeNumberLen1%18
  WholeNumberSize2 = WholeNumberLen2/18
  WholeNumberRemainder2 = WholeNumberLen2%18
  ;*******************************************************************
  ;Clean up from previous call
  ;*******************************************************************
  result.s = ""
  If WholeNumberSize1>WholeNumberSize2
    count = WholeNumberSize1 + 1;Number of Registers to Add
    For z = 1 To count
      WholeNumber2(z) = 0;Clear Out Unused Registers this session
      WholeNumberCarry(z) = 0;Clear out Carry Flags
    Next
  Else
    count = WholeNumberSize2 + 1;Number of Registers to Add
    For z = 1 To count
      WholeNumber1(z) = 0;Clear Out Unused Registers this session
      WholeNumberCarry(z) = 0;Clear Out Carry Flags
    Next
  EndIf
  ;********************************************************************
  ;Get Large Numbers out of Strings in 18 char chunks for Quad Math
  ;********************************************************************
  For z = 1 To WholeNumberSize1
    WholeNumber1(z) = Val(Mid(string1, (WholeNumberLen1-(z*18)) + 1, 18));????Len+1 why? Needs fixed
  Next
  
  WholeNumber1(z) = Val(Mid(string1, 1, WholeNumberRemainder1));Here Z is already incremented by the For Loop on Exit
  
  For z = 1 To WholeNumberSize2
    WholeNumber2(z) = Val(Mid(string2, (WholeNumberLen2-(z*18)) + 1, 18));????Len+1 why? Needs fixed
  Next
  WholeNumber2(z) = Val(Mid(string2, 1, WholeNumberRemainder2));Here Z is already incremented by the For Loop on Exit
  ;(++)= Add,  Answer is Positive***************************************************
  If Not wholeNumberNegative1 And Not wholeNumberNegative2
    Goto ADD
  EndIf
  ;(--)= Add,  Answer is negative***************************************************
  If wholeNumberNegative1 And wholeNumberNegative2
    result = "-"
    Goto ADD
  EndIf
  
  ;*******************************************************************
  ;If we get here its a Subtraction Problem
  ;*******************************************************************
  ;Now we must Do String Size Compare--Cycle eater right here :)
  ;*******************************************************************
  If WholeNumberLen2<WholeNumberLen1
    Compare = #False
    
  ElseIf WholeNumberLen2>WholeNumberLen1
    
    Compare = #True
  Else
    For z = count To 1 Step -1
      If WholeNumber2(z)>WholeNumber1(z)
        Compare = #True
        Break
      Else
        Compare = #False
        Break
      EndIf
    Next
  EndIf
  ;*******************************************************************
  ;Logic for sticking Biggest Number on Top
  ;*******************************************************************
  If compare = #True And WholeNumberNegative2
    ;String2> and is Negative
    result = "-"
    Goto AddISubString2isBigger
  EndIf
  If Compare = #True And Not WholeNumberNegative2
    ;String2> and is Positive
    Goto AddISubString2isBigger
  EndIf
  If compare = #False And WholeNumberNegative1
    ;String1> and is Negative
    result = "-"
    Goto AddISubString1isBigger
  EndIf
  ;*******************************************************************
  ;If We get here answer is Positive?
  ;*******************************************************************
  ;result=""
  Goto AddISubString1isBigger
  
  ;***********************************************************
  ;Add here
  ;***********************************************************
  Add:
  For z = 1 To count
    WholeNumber1(z) = WholeNumber1(z) + WholeNumber2(z); + WholeNumberCarry(z)
    If WholeNumber1(z)>999999999999999999
      WholeNumber1(z + 1) + 1 ;WholeNumberCarry(z + 1) = 1
      WholeNumber1(z)-1000000000000000000
    EndIf
  Next
  Goto AddEnd
  AddISubString1isBigger:
  
  For z = 1 To count
    If WholeNumber1(z)<WholeNumber2(z);Borrow
      WholeNumber1(z) + 1000000000000000000 ;! 1000000000000000000;
      wholeNumber1(z + 1)-1;000000000000000000
    EndIf
    WholeNumber1(z) = WholeNumber1(z)-WholeNumber2(z) ;+ WholeNumberCarry(z)
  Next
  If WholeNumber1(count)<-999999999999999999
    wholeNumber1(count) + 1000000000000000000
  EndIf
  ;       If WholeNumber1(count)<0
  ;         WholeNumber1(count) = -WholeNumber1(count);+ 1000000000000000000
  ;       EndIf
  ;
  ;   If WholeNumber1(count)>999999999999999999
  ;     WholeNumber1(count) + 1000000000000000000
  ;   EndIf
  Goto SubAddIEnd
  AddISubString2isBigger:
  For z = 1 To count
    If WholeNumber2(z)<WholeNumber1(z);Borrow
      WholeNumber2(z) + 1000000000000000000 ;! 1000000000000000000;
      wholeNumber2(z + 1)-1;000000000000000000
    EndIf
    WholeNumber1(z) = WholeNumber2(z)-WholeNumber1(z) ;+ WholeNumberCarry(z)
    
  Next
  ;   If WholeNumber1(count)<0
  ;     WholeNumber1(count) = -WholeNumber1(count);+ 1000000000000000000
  ;   EndIf
  
  If WholeNumber1(count)<-999999999999999999
    wholeNumber1(count) + 1000000000000000000
  EndIf
  ;   If WholeNumber1(count)>999999999999999999
  ;     WholeNumber1(count) + 1000000000000000000
  ;   EndIf
  
  Goto SubAddIEnd
  
  AddEnd:
  If WholeNumber1(count) = 0
    result + Str(WholeNumber1(count-1))
    For z = count-2 To 1 Step -1
      ;temp=Str(WholeNumber1(z))
      result + RSet(Str(WholeNumber1(z)), 18, "0");Merge18r(Str(WholeNumber1(z)));Merge18r(temp);RSet(Str(WholeNumber1(z)), 18, "0");RMerge18(Str(WholeNumber1(z)))
    Next
  Else
    result + Str(WholeNumber1(count))
    For z = count-1 To 1 Step -1
      ;temp = Str(WholeNumber1(z))
      result + RSet(Str(WholeNumber1(z)), 18, "0");Merge18r(Str(WholeNumber1(z)));Merge18r(temp);RSet(Str(WholeNumber1(z)), 18, "0")
    Next
  EndIf
  ProcedureReturn result
  SubAddIEnd:
  If WholeNumber1(count) = 0 ;Or
    result + Str(WholeNumber1(count-1))
    For z = count-2 To 1 Step -1
      If WholeNumber1(z)<0
        WholeNumber1(z) = -WholeNumber1(z)
      EndIf
      ;temp=Str(WholeNumber1(z))
      result + RSet(Str(WholeNumber1(z)), 18, "0");Merge18r(Str(WholeNumber1(z)));Merge18r(temp);RSet(Str(WholeNumber1(z)), 18, "0");RMerge18(Str(WholeNumber1(z)))
    Next
  Else
    result + Str(WholeNumber1(count))
    For z = count-1 To 1 Step -1
      If WholeNumber1(z)<0
        WholeNumber1(z) = -WholeNumber1(z);Make sure Negative sign dont show in result until the end
      EndIf
      ;temp = Str(WholeNumber1(z))
      result + RSet(Str(WholeNumber1(z)), 18, "0");Merge18r(Str(WholeNumber1(z)));Merge18r(temp);RSet(Str(WholeNumber1(z)), 18, "0")
    Next
  EndIf
  ProcedureReturn result
EndProcedure
ProcedureDLL.s RealFastAddI(String1.s, String2.s);RealFastAddI (Integer1,Integer2) No SIGN Support
  WholeNumberLen1 = Len(String1)
  WholeNumberLen2 = Len(String2)
  WholeNumberSize1 = WholeNumberLen1/18
  WholeNumberRemainder1 = WholeNumberLen1%18
  WholeNumberSize2 = WholeNumberLen2/18
  WholeNumberRemainder2 = WholeNumberLen2%18
  ;*******************************************************************
  ;Clean up from previous call
  ;*******************************************************************
  result.s = ""
  If WholeNumberSize1>WholeNumberSize2
    count = WholeNumberSize1 + 1;Number of Registers to Add
    For z = 1 To count
      WholeNumber2(z) = 0;Clear Out Unused Registers this session
      WholeNumberCarry(z) = 0;Clear out Carry Flags
    Next
  Else
    count = WholeNumberSize2 + 1;Number of Registers to Add
    For z = 1 To count
      WholeNumber1(z) = 0;Clear Out Unused Registers this session
      WholeNumberCarry(z) = 0;Clear Out Carry Flags
    Next
  EndIf
  ;********************************************************************
  ;Get Large Numbers out of Strings in 18 char chunks for Quad Math
  ;********************************************************************
  For z = 1 To WholeNumberSize1
    WholeNumber1(z) = Val(Mid(string1, (WholeNumberLen1-(z*18)) + 1, 18));????Len+1 why? Needs fixed
  Next
  
  WholeNumber1(z) = Val(Mid(string1, 1, WholeNumberRemainder1));Here Z is already incremented by the For Loop on Exit
  
  For z = 1 To WholeNumberSize2
    WholeNumber2(z) = Val(Mid(string2, (WholeNumberLen2-(z*18)) + 1, 18));????Len+1 why? Needs fixed
  Next
  WholeNumber2(z) = Val(Mid(string2, 1, WholeNumberRemainder2));Here Z is already incremented by the For Loop on Exit
  
  For z = 1 To count
    WholeNumber1(z) = WholeNumber1(z) + WholeNumber2(z) + WholeNumberCarry(z)
    If WholeNumber1(z)>999999999999999999
      WholeNumber1(z + 1) + 1;WholeNumberCarry(z + 1) = 1
      WholeNumber1(z)-1000000000000000000
    EndIf
  Next
  
  If WholeNumber1(count) = 0
    result + Str(WholeNumber1(count-1))
    For z = count-2 To 1 Step -1
      ;temp=Str(WholeNumber1(z))
      result + RSet(Str(WholeNumber1(z)), 18, "0");Merge18r(Str(WholeNumber1(z)));Merge18r(temp);RSet(Str(WholeNumber1(z)), 18, "0");RMerge18(Str(WholeNumber1(z)))
    Next
  Else
    result + Str(WholeNumber1(count))
    For z = count-1 To 1 Step -1
      ;temp = Str(WholeNumber1(z))
      result + RSet(Str(WholeNumber1(z)), 18, "0");Merge18r(Str(WholeNumber1(z)));Merge18r(temp);RSet(Str(WholeNumber1(z)), 18, "0")
    Next
  EndIf
  ProcedureReturn result
EndProcedure
ProcedureDLL.s RealFastAddF(String1.s, String2.s);RealFastAddF (Float1,Float2) No SIGN Support
  ;   Result.s = "Sorry, Not Implemented Yet."
  ;
  ;   ProcedureReturn Result.s
  WholeNumberLen1 = Len(String1)
  WholeNumberLen2 = Len(String2)
  DecimalPoint1 = FindString(String1, ".", 0)
  DecimalPoint2 = FindString(String2, ".", 0)
  temp1.s = Mid(string1, DecimalPoint1 + 1, WholeNumberLen1)
  PercentStringLen1 = Len(temp1);We Need percent Len to pad for addition
  temp2.s = Mid(string2, DecimalPoint2 + 1, WholeNumberLen2)
  PercentStringLen2 = Len(temp2);We Need percent Len to pad for addition
  DecimalPoint = WholeNumberLen1-DecimalPoint1;we do this in case both lens are equal; needs optimized to cut out cycles
  If PercentStringLen1>PercentStringLen2
    temp2 = LSet(temp2, PercentStringLen1, "0");  We pad, Dont for get to change Len!
    DecimalPoint = WholeNumberLen1-DecimalPoint1;set where we stick the decimal after adding
    wholeNumberLen2 + Len(temp2)-PercentStringLen2;change Len
  EndIf
  If PercentStringLen2>PercentStringLen1
    Temp1 = LSet(Temp1, PercentStringLen2, "0");  We pad, Dont for get to change Len!
    DecimalPoint = WholeNumberLen2-DecimalPoint2;set where we stick the decimal after adding
    wholeNumberLen1 + Len(temp1)-PercentStringLen1;change Len
  EndIf
  
  string1 = Mid(string1, 1, DecimalPoint1-1) + temp1;Strip out Decimal Point so We can Add Like Normal
  WholeNumberLen1-1;Len=Len-1 now because we took out Decimal Point
  
  string2 = Mid(string2, 1, DecimalPoint2-1) + temp2;Strip out Decimal Point so We can Add Like Normal
  WholeNumberLen2-1;Len=Len-1 now because we took out Decimal Point
  
  WholeNumberSize1 = WholeNumberLen1/18
  WholeNumberRemainder1 = WholeNumberLen1%18
  WholeNumberSize2 = WholeNumberLen2/18
  WholeNumberRemainder2 = WholeNumberLen2%18
  
  ;*******************************************************************
  ;Clean up from previous call
  ;*******************************************************************
  result.s = ""
  If WholeNumberSize1>WholeNumberSize2
    count = WholeNumberSize1 + 1;Number of Registers to Add
    For z = 1 To count
      WholeNumber2(z) = 0;Clear Out Unused Registers this session
      WholeNumberCarry(z) = 0;Clear out Carry Flags
    Next
  Else
    count = WholeNumberSize2 + 1;Number of Registers to Add
    For z = 1 To count
      WholeNumber1(z) = 0;Clear Out Unused Registers this session
      WholeNumberCarry(z) = 0;Clear Out Carry Flags
    Next
  EndIf
  
  For z = 1 To WholeNumberSize1
    WholeNumber1(z) = Val(Mid(string1, (WholeNumberLen1-(z*18)) + 1, 18));????Len+1 why? Needs fixed
  Next
  
  WholeNumber1(z) = Val(Mid(string1, 1, WholeNumberRemainder1));Here Z is already incremented by the For Loop on Exit
  
  For z = 1 To WholeNumberSize2
    WholeNumber2(z) = Val(Mid(string2, (WholeNumberLen2-(z*18)) + 1, 18));????Len+1 why? Needs fixed
  Next
  WholeNumber2(z) = Val(Mid(string2, 1, WholeNumberRemainder2));Here Z is already incremented by the For Loop on Exit
  
  For z = 1 To count
    WholeNumber1(z) = WholeNumber1(z) + WholeNumber2(z) + WholeNumberCarry(z)
    If WholeNumber1(z)>999999999999999999;there was a carry
      WholeNumberCarry(z + 1) = 1;set carry on next register add
      WholeNumber1(z)-1000000000000000000;remove the carry from this register
    EndIf
  Next
  
  If WholeNumber1(count) = 0
    result + Str(WholeNumber1(count-1))
    For z = count-2 To 1 Step -1
      ;temp=Str(WholeNumber1(z))
      result + RSet(Str(WholeNumber1(z)), 18, "0");Merge18r(Str(WholeNumber1(z)));Merge18r(temp);RSet(Str(WholeNumber1(z)), 18, "0");RMerge18(Str(WholeNumber1(z)))
    Next
  Else
    result + Str(WholeNumber1(count))
    For z = count-1 To 1 Step -1
      ;temp = Str(WholeNumber1(z))
      result + RSet(Str(WholeNumber1(z)), 18, "0");Merge18r(Str(WholeNumber1(z)));Merge18r(temp);RSet(Str(WholeNumber1(z)), 18, "0")
    Next
  EndIf
  ProcedureReturn Mid(result, 1, Len(result)-DecimalPoint) + "." + Mid(result, Len(result)-DecimalPoint + 1, Len(result));result
  
EndProcedure
ProcedureDLL.s RealMulI(String1.s, String2.s)
  #MultiplyDigits=18
  
  WholeNumberLen1 = Len(String1)
  WholeNumberLen2 = Len(String2)
  If Mid(String1, 1, 1) = "-"
    WholeNumberNegative1 = #True
    string1 = Mid(string1, 2, WholeNumberLen1);Remove Sign
    WholeNumberLen1-1
  Else
    WholeNumberNegative1 = #False
  EndIf
  If Mid(String2, 1, 1) = "-"
    WholeNumberNegative2 = #True
    string2 = Mid(string2, 2, WholeNumberLen2);Remove Sign
    WholeNumberLen2-1
  Else
    WholeNumberNegative2 = #False
  EndIf
  ;********************************************************************
  ;Calculate the sign of the answer
  ;********************************************************************
  If WholeNumberNegative1 = #True And WholeNumberNegative2 = #False
    result.s = "-"
  ElseIf WholeNumberNegative1 = #False And WholeNumberNegative2 = #True
    result.s = "-"
  Else
    result.s = ""
  EndIf
  
  WholeNumberSize1 = WholeNumberLen1/#MultiplyDigits
  WholeNumberRemainder1 = WholeNumberLen1%#MultiplyDigits
  WholeNumberSize2 = WholeNumberLen2/#MultiplyDigits
  WholeNumberRemainder2 = WholeNumberLen2%#MultiplyDigits
  ;*******************************************************************
  ;Clean up from previous call
  ;*******************************************************************
  resultTemp.s = ""
  ;*****************************
  ;WholeNumber2 is Multiplier Here This is not Finished yet
  ;*****************************
  ;If WholeNumberSize1>WholeNumberSize2
  count = WholeNumberSize1; + 1;Number of Registers to Add
  
  
  For z = 1 To count
    WholeNumber2(z) = 0;Clear Out Unused Registers this session
    WholeNumber1(z) = 0
    ;WholeNumberCarry(z) = 0;Clear out Carry Flags
  Next
  ;*****************************************************************
  ;   Else
  ;     ;*****************************
  ;     ;WholeNumber1 is Multiplier Here Not Finished yet:  Working on WholeNumber2 first
  ;     ;*****************************
  ;     count = WholeNumberSize2; + 1;Number of Registers to Add
  ;     If WholeNumberRemainder2>0
  ;       Count + 1
  ;     EndIf
  ;     count2 = WholeNumberSize1; + 1
  ;     If WholeNumberRemainder1>0
  ;       count2 + 1
  ;     EndIf
  ;     For z = 1 To count
  ;       WholeNumber1(z) = 0;Clear Out Unused Registers this session
  ;       ;WholeNumberCarry(z) = 0;Clear Out Carry Flags
  ;     Next
  ;   EndIf
  ;********************************************************************
  ;Get Large Numbers out of Strings in 18 char chunks for Quad Multiply
  ;********************************************************************
  For z = 1 To WholeNumberSize1
    WholeNumber1(z) = Val(Mid(string1, (WholeNumberLen1-(z*#MultiplyDigits)) + 1, #MultiplyDigits));????Len+1 why? Needs fixed
    PartialProduct(z) = WholeNumber1(z)
    PartialProductTemp(z) = WholeNumber1(z)
  Next
  
  WholeNumber1(z) = Val(Mid(string1, 1, WholeNumberRemainder1));Here Z is already incremented by the For Loop on Exit
  PartialProduct(z) = WholeNumber1(z)
  PartialProductTemp(z) = WholeNumber1(z)
  
  For z = 1 To WholeNumberSize2
    WholeNumber2(z) = Val(Mid(string2, (WholeNumberLen2-(z*#MultiplyDigits)) + 1, #MultiplyDigits));????Len+1 why? Needs fixed
    ;*******************************************************************
    ;Count Multiplier bits;  We are trying a type of HomeMade algo here
    ;*******************************************************************
    
  Next
  WholeNumber2(z) = Val(Mid(string2, 1, WholeNumberRemainder2));Here Z is already incremented by the For Loop on Exit
  BitCount1.q = Count*60;60 here if 18 digits, 30 for 9 digits
  If WholeNumberRemainder1>0;May Be Able to cut out this code later for optimization
    count + 1
    BitCountRemainder1.i = Len(Bin(WholeNumber1(count)))
    BitCount1.q + BitCountRemainder1
  Else
    BitCountRemainder1.i = Len(Bin(WholeNumber1(count)))
  EndIf
  
  Count2 = WholeNumberSize2; + 1
  If wholeNumberSize2 = 0
    BitCount2.q = Len(Bin(WholeNumber2(1)))
    ;PrintN(Bin(wholenumber2(1)))
  Else
    BitCount2.q = Count2*60;WholeNumber2 BitCount
  EndIf
  
  
  If WholeNumberRemainder2>0 And wholenumber2>0
    
    Count2 + 1
    BitCountRemainder2.i = Len(Bin(WholeNumber2(count2)))
    BitCount2.q + BitCountRemainder2.i
  Else
    BitCountRemainder2.i = Len(Bin(WholeNumber2(count2)))
  EndIf
  ;*******************************************************************
  ;Count Multiplier bits;  We are trying a type of Booth algo here
  ;*******************************************************************
  ;   If wholeNumber2(z)>0
  ;     MultiplierBits + Len(Bin(wholeNumber2(z)))
  ;   EndIf
  ;   If WholeNumber2(1) & 1;  This is Odd
  ;     ;MultiplierBits+1
  ;   Else;If its even Bitwork is one less
  ;     ;MultiplierBits-1
  ;   EndIf
  ;PrintN(Str(multiplierbits))
  ;   AddCount = 1
  ;   Multiply = 1
  
  ;**************************************************************************
  ;First we have the Initial Number of shifts we need for WholeNumber1()
  ;Register in BitCount.  So wholenumber1() is going to get shifted this
  ;many times To start. Then we need Next power of 2 so we can shift
  ;PartialProduct. Then we take Partial product and add to WholeNumber1().
  ;Repeat original partial product shifts until Next Power of 2=1 or 0.  If
  ;equal 1 we add one more time before returning result.
  ;**************************************************************************
  
  ;******************************************************************************
  ;Multiplier < Multiplicand Section
  ;Shift WholeNumber1 left BitCount Times.  This is our first power of 2 shift.
  ;If multiplier is a power of 2 we will be done after this shift.
  ;******************************************************************************
  CountRegister = BitCountRemainder1.i
  BitCountTemp2 = BitCount2
  
  While BitCountTemp2>1;Multiplier is WholeNumber2()
    For z = count To 1 Step-1 ;Left Shift  Count to 1 is for proper carry!  Do Not change
      WholeNumber1(z)<<1; + WholeNumberCarry(z)
      If WholeNumber1(z)>999999999999999999;We need to carry
        WholeNumber1(z + 1) + 1 ;Do the carry
        WholeNumber1(z)-1000000000000000000;Take the overflow back away
      EndIf
    Next
    BitCountTemp2-1
    CountRegister + 1
    If CountRegister>#MultiplyDigits
      Count + 1
      CountRegister = 0
    EndIf
  Wend
  ;**************************************************************************
  ;Now we need to determine Next Power of 2 for next shifts on Partial Product
  ;or final add
  ;**************************************************************************
  
;   MultiplyShiftsLabel:
;   While MultiplierBits>0
;     If WholeNumber2(1) & 3
;       PrintN("Add WholeNumber and PartialProduct" + " Multiplier Bits=" + Str(MultiplierBits))
;       For z = 1 To count;Add WholeNumber and PartialProduct
;         WholeNumber1(z) = WholeNumber1(z) + PartialProduct(z); + WholeNumberCarry(z)
;         If WholeNumber1(z)>999999999
;           WholeNumber1(z + 1) + 1 ;WholeNumberCarry(z + 1) = 1
;           WholeNumber1(z)-1000000000
;         EndIf
;       Next
;       For z = count2 To 1 Step -1;RightShift Multiplier
;         If WholeNumber2(z) & 1
;           WholeNumber2(z-1) + 1000000000
;         EndIf
;         WholeNumber2(z)>>1
;       Next
;       MultiplierBits-1
;     Else;Right Shift Multiplier and LeftShift Muliplcand
;       PrintN("Left shift and right shift" + " Multiplier Bits=" + Str(MultiplierBits))
;       For z = count To 1 Step-1 ;Left Shift
;         
;         WholeNumber1(z)<<1; + WholeNumberCarry(z)
;         If WholeNumber1(z)>999999999
;           
;           ;WholeNumber1(z + 1)<<1
;           WholeNumber1(z + 1) + 1 ;WholeNumberCarry(z + 1) = 1
;           ;z + 1
;           
;           WholeNumber1(z)-1000000000
;         EndIf
;       Next
;       ;count+1
;       ; RightShiftMultiplier:
;       For z = count2 To 1 Step -1
;         If WholeNumber2(z) & 1
;           WholeNumber2(z-1) + 1000000000
;         EndIf
;         WholeNumber2(z)>>1
;       Next
;       MultiplierBits-1
;     EndIf
;   Wend
  
  ;   While Multiply <=  Count2
  ;     For z = 1 To count
  ;       MultiplyAdd.s(AddCount) = Str(WholeNumber1(z)*WholeNumber2(Multiply)) + LSet("", ((z-1)*9) + ((Multiply-1)*9), "0");LSet(, ((z-1)*9) + ((Multiply-1)*9), "0"); + WholeNumberCarry(z)
  ;       AddCount + 1
  ;     Next
  ;     Multiply + 1
  ;   Wend
  ;   For z = 1 To addcount
  ;     PrintN(MultiplyAdd(z))
  ;   Next
  ;   For z = 1 To addcount
  ;     resulttemp.s=RealFastAddI(resultTemp.s,MultiplyAdd(z))
  ;   Next
  If WholeNumber1(count) = 0
  ;PrintN("First")
    result + Str(WholeNumber1(count-1))
    For z = count-2 To 1 Step -1
      ;temp=Str(WholeNumber1(z))
      result + RSet(Str(WholeNumber1(z)), #MultiplyDigits, "0");Merge18r(Str(WholeNumber1(z)));Merge18r(temp);RSet(Str(WholeNumber1(z)), 18, "0");RMerge18(Str(WholeNumber1(z)))
    Next
  Else
  ;PrintN("Second")
    result + Str(WholeNumber1(count))
    For z = count-1 To 1 Step -1;
      ;temp = Str(WholeNumber1(z))
      result + RSet(Str(WholeNumber1(z)), #MultiplyDigits, "0");Merge18r(Str(WholeNumber1(z)));Merge18r(temp);RSet(Str(WholeNumber1(z)), 18, "0")
    Next
  EndIf
  ProcedureReturn result.s;+resultTemp
EndProcedure

RealMathInit()
OpenConsole()
timer = ElapsedMilliseconds()
answer.s = "0"
String1.s = "1" : String2.s = "2";987654312098765433
For a = 1 To 10;0;000;6;00;0
  ;   var1.q = Random(922337203685477580)
  ;   Var2.q = Random(922337203685477580)
  ;   pos1 = Random(2)
  ;   pos2 = Random(2)
  ;   If pos1 = 2
  ;     var1 = -var1
  ;
  ;   EndIf
  ;   If pos2 = 2
  ;     var2 = -var2
  ;   EndIf
  ;   string1 = Str(var1)
  ;   string2 = Str(var2)
  answer.s = RealmulI(string1, string2)
  ;   Check.q = var1+var2
  ;   If Str(check)<>answer
  ;     PrintN("Error!!" + string1 + " - " + string2 + "=" + Str(check))
  ;     Input()
  ;   EndIf
  ;string2 = answer
  string1 = answer
  
 PrintN(Str(a) + "  " + "Answer=  " + answer + "  " + Str(Len(answer)))
Next
PrintN("Answer=  " + answer)

PrintN("time taken was " + StrF((ElapsedMilliseconds()-timer)/1000) + " Seconds")
PrintN("Digits=" + Str(Len(answer)))
Input()
End

Post Reply