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
.
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