and thought it might be funny to do it with AHK.
You can now add, subtract and multiply positive or negative
Integers with hunderts of digits
Here the code:
#SingleInstance force Gui, Add, Text, x10 y30 w51 h15, BigNum 1: Gui, Add, Button, x65 y24 w25 h25 gPM1, +/- Gui, Add, Edit, vLong1 r2 Number -WantReturn x96 y20 w350 h46,63562623 Gui, Add, Button, x96 y60 w55 h23, &Swap Gui, Add, Button, x155 y60 w55 h23, &Compare Gui, Add, Button, x214 y60 w55 h23, B1 + B2 Gui, Add, Button, x273 y60 w55 h23, B1 - B2 Gui, Add, Button, x332 y60 w55 h23, B1 * B2 Gui, Add, Button, x391 y60 w55 h23, B1 / B2 Gui, Add, Text, x10 y101 w51 h15, BigNum 2: Gui, Add, Button, x65 y94 w25 h25 gPM2, +/- Gui, Add, Edit, vLong2 r2 Number -WantReturn x96 y90 w350 h42,6355334 Gui, Add, Text, x96 y130 w350 h35, ( Type in some large Integers (positive or negative) and test it ) Gui, Add, Text, x10 y160 w51 h15, Result: Gui, Add, Edit, VResultEdit readonly x96 y160 w350 h107, Gui, Show, x270 y110 h277 w477, BigInteger-Package by Rubberduck Esc::exitApp return ;************************************************************************** ;****** Internal Help-functions ;************************************************************************** ;//returns the maximum of x and y Max(x,y) { IfLess x,%y%, Return y Return x } ;//simplyfies the use of Transform Mod(In_Dividend,In_Divisor) { Transform, Ret_Val, Mod, %In_Dividend%, %In_Divisor% return Ret_Val } ;//simplyfies the use of Transform Div(In_Dividend,In_Divisor) { Transform, Ret_Val, Floor, In_Dividend/In_Divisor return, Ret_Val } ;//Also usefull for any AHK-script. Swap the values of two variables Swap_Values(Byref val1, ByRef Val2) { local dummy dummy:=val1 val1:=val2 val2:=dummy } ;//Is removing leading zeros from an LongInt String. If the String holds ;//an leading Minus it is kept -0000123 => -123 and 00985 => 985 RemoveLeadingZeros(ByRef LongIntString) { local LCh, ZCh, WS WS=%LongIntString% StringLeft, LCh, WS, 1 if (LCh="-") StringTrimLeft,WS,WS,1 loop { StringLeft, ZCh,WS,1 if (ZCh="0") StringTrimLeft,WS,WS,1 else break } If (WS="") ;//If it is empty now make it 0 WS=0 if (LCh="-") ;//Add minus again if there was one WS=-%WS% LongIntString=%WS% ;//returns result BYREF !!!! } ;//This function is comparing IntegerStrings (also WITH leading Minus) ;//Leading Zeros are removed by default to make comparison possible ;//If First is smaller than Second -1 is returned ;//If First and Second are equal 0 is returned ;//If First is bigger than Second 1 is returned ;//If one of the Strings is empty it is assumed to be 0 CompareLongIntStrings(ByRef FirstLongString,Byref SecondLongString,ShowMessage) { local FSize, FCh, SSize, SCh, Output, Ret_Val RemoveLeadingZeros(FirstLongString) RemoveLeadingZeros(SecondLongString) StringLen, FSize, FirstLongString StringLen, SSize, SecondLongString StringLeft, FCh, FirstLongString, 1 StringLeft, SCh, SecondLongString, 1 if (FCh="-")and(SCh<>"-") Ret_Val=-1 else if (SCh="-")and(FCh<>"-") Ret_Val=1 else { if (FSize>SSize) { if (FCh="-")and(SCh="-") Ret_Val=-1 else Ret_Val=1 } else if (SSize>FSize) { if (FCh="-")and(SCh="-") Ret_Val=1 else Ret_Val=-1 } else if (SSize=FSize) { Ret_Val=0 ;//assume we find no difference loop, %SSize% { StringMid, Dig1, FirstLongString, %A_index%, 1 StringMid, Dig2, SecondLongString, %A_index%, 1 if (Dig1<>Dig2) ;//Found a different digit { if (Dig1>Dig2) { If (FCh="-")and(SCh="-") Ret_Val=-1 else Ret_Val=1 break } else if (Dig2>Dig1) { If (FCh="-")and(SCh="-") Ret_Val=1 else Ret_Val=-1 break } } } } } if (ShowMessage=1) { if (Ret_Val=-1) OutPut=BigNum 1 is smaller than BigNum 2 else if (Ret_Val=1) OutPut=BigNum 1 is bigger than BigNum 2 else OutPut=Both BigNum's are equal GuiControl,, ResultEdit, %OutPut% } return, Ret_Val } ;//Returns 1 if LongIntString has a leading Minus else returns 0 IsNeg(LongIntString) { local MCh StringLeft, MCh,LongIntString,1 if (MCh="-") return, 1 else return, 0 } ;//Returns a LongIntString with removed Minus, what ;//simply means it returns an ABS'd LongIntString ABSLongintString(LongIntString) { local MCh StringLeft, MCh, LongIntString, 1 if (MCh="-") { StringTrimLeft,LongIntString,LongIntString,1 return %LongIntString% } else return %LongIntString% } ;//Is adding leading zeros to the strings so they have same length ;//leading Minus is kept. We add 3 reserve-zeros MakeFitLength(ByRef FirstLongString,Byref SecondLongString) { local LS1Size, LS2Size, FCh, SCh, Maxi, L1Diff, L2Diff RemoveLeadingZeros(FirstLongString) RemoveLeadingZeros(SecondLongString) StringLeft, FCh, FirstLongString, 1 StringLeft, SCh, SecondLongString, 1 ;//remove minus first if there are one if (FCh="-") StringTrimLeft,FirstLongString,FirstLongString,1 if (SCh="-") StringTrimLeft,SecondLongString,SecondLongString,1 StringLen, LS1Size, FirstLongString StringLen, LS2Size, SecondLongString Maxi:=Max(LS1Size,LS2Size) L1Diff:=Maxi-LS1Size+3 L2Diff:=Maxi-LS2Size+3 loop, %L1Diff% FirstLongString=0%FirstLongString% loop, %L2Diff% SecondLongString=0%SecondLongString% ;//Put back Minus if there was one if (FCh="-") FirstLongString=-%FirstLongString% if (SCh="-") SecondLongString=-%SecondLongString% } ;//This function is subtracting Second from first and ALWAYS awaits ;//positiveONLY Strings (leading zeros already removed), AND that First is ;//bigger than second so the result always will be positive e.g. 1000-456=544. ;//This function is only for internal use and called by the real ADD-SUB-Functions ABSLongIntStringSub(FirstLongString,SecondLongString) { local MaxLength, ResultString, Erg, value1, value2, Sum, Rem Rem = 0 ResultString = StringLen, MaxLength, FirstLongString loop, %MaxLength% { StringMid,value1,FirstLongString,MaxLength+1-A_index,1 StringMid,value2,SecondLongString,MaxLength+1-A_index,1 Sum:=value1-(value2+rem) Rem:=Div((9-sum),10) Erg:=Mod((sum+10),10) ResultString=%Erg%%ResultString% } return, %Resultstring% } ;//This is the REAL Function that is able to subtract one LongIntString ;//from another. Is subtracting Second from First (LongStrings) and returns the ;//Result as STRING. Now is supporting positive AND negative Long-Integers LongIntStringSub(FirstLongString,SecondLongString) { local WS1, WS2, WSResult, FIsNeg, SIsNeg, ABSCompi ;//remember the minus FIsNeg:=IsNeg(FirstLongString) SIsNeg:=IsNeg(SecondLongString) ;//remove the minus on workstrings WS1:=ABSLongIntString(FirstLongString) WS2:=ABSLongIntString(SecondLongString) ;//compare absolute size of BigNums ABSCompi:=CompareLongintStrings(WS1,WS2,0) ;//Make Strings same length with added zeroes MakeFitLength(WS1,WS2) If (FIsNeg="0" and SIsNeg="1") ;//First pos, second neg. "x - -y" => "(x+y)" WSResult:=ABSLongIntStringAdd(WS1,WS2) else If (FIsNeg="1" and SIsNeg="0") ;//First neg, sec pos. "-x - y" => "-(x+y)" WSResult:=-ABSLongIntStringAdd(WS1,WS2) else If (FIsNeg="1" and SIsNeg="1") ;//Both are negative { if (ABSCompi=0) ;//Both are same ABS-size. E.G. -5 - -5 => Result 0 return, 0 else if (ABSCompi=1) ;//E.G. -1000 - -20 = -980 => Result negative WSResult:=-ABSLongIntStringSub(WS1,WS2) else if (ABSCompi=-1) ;//E.G. -20 - -1000 = +980 => Result positive WSResult:=ABSLongIntStringSub(WS2,WS1) } else If (FIsNeg="0" and SIsNeg="0") ;//Both are positive { if (ABSCompi=0) ;//Both are same ABS-size. E.G. 5 - 5 => Result 0 return, 0 else if (ABSCompi=1) ;//E.G. 1000 - 20 = 980 => Result positive WSResult:=ABSLongIntStringSub(WS1,WS2) else if (ABSCompi=-1) ;//E.G. 20 - 1000 = -980 => Result negative WSResult:=-ABSLongIntStringSub(WS2,WS1) } RemoveLeadingZeros(WSResult) return, %WSResult% } ;//This function is adding First and Second and always awaits Strings ;//(minuses removed) and prepared with MakeFitLength() ;//This function is only for internal use and called by the real ADD-SUB-Functions ABSLongIntStringAdd(FirstLongString,SecondLongString) { local MaxLength, ResultString, Erg, value1, value2, sum, Rem Rem = 0 ResultString = StringLen, MaxLength, FirstLongString loop, %MaxLength% { StringMid,value1,FirstLongString,MaxLength+1-A_index,1 StringMid,value2,SecondLongString,MaxLength+1-A_index,1 Sum:=Value1+Value2+rem Erg:=Mod(Sum,10) Rem:=Div(Sum,10) ResultString=%Erg%%ResultString% } return, %Resultstring% } ;//Is adding two LongIntSTRINGS LongIntStringAdd(FirstLongString,SecondLongString) { local WS1, WS2, WSResult, FIsNeg, SIsNeg, ABSCompi ;//remember the minus FIsNeg:=IsNeg(FirstLongString) SIsNeg:=IsNeg(SecondLongString) ;//remove the minus on workstrings WS1:=ABSLongIntString(FirstLongString) WS2:=ABSLongIntString(SecondLongString) ;//compare absolute size of BigNums ABSCompi:=CompareLongintStrings(WS1,WS2,0) ;//Make Strings same length with added zeroes MakeFitLength(WS1,WS2) If (FIsNeg="0" and SIsNeg="0") ;//Both positive =>Result positive WSResult:=ABSLongIntStringAdd(WS1,WS2) else If (FIsNeg="1" and SIsNeg="1") ;//Both negative =>Result negative WSResult:=-ABSLongIntStringAdd(WS1,WS2) else If (FIsNeg="1" and SIsNeg="0") ;//First negative, Second positive, further checking { if (ABSCompi=0) ;//Both are same ABS-size. E.G. -5 + 5 => Result 0 return, 0 else if (ABSCompi=1) ;//E.G. -1000 + 20 = -980 => Result negative WSResult:=-ABSLongIntStringSub(WS1,WS2) else if (ABSCompi=-1) ;//-20 + 1000 = +980 => Result positive WSResult:=ABSLongIntStringSub(WS2,WS1) } else If (FIsNeg="0" and SIsNeg="1") ;//First positive, Second negative, further checking { if (ABSCompi=0) ;//Both are same ABS-size. E.G. 5 + -5 => Result 0 return, 0 else if (ABSCompi=1) ;//E.G. 1000 + -20 = +980 => Result positive WSResult:=ABSLongIntStringSub(WS1,WS2) if (ABSCompi=-1) ;//E.G. 20 + -1000 = -980 => Result negative WSResult:=-ABSLongIntStringSub(WS2,WS1) } RemoveLeadingZeros(WSResult) return, %WSResult% } StringGetChar(In_String,In_Posi,Param3) { local Length, Ret_Val Ret_Val = StringLen, Length, In_String if (In_Posi>Length)or(length=0)or(In_Posi<1) return Ret_Val If (Param3=R) StringMid,Ret_Val,In_String,Length+1-In_Posi,1 else StringMid,Ret_Val,In_String,In_Posi,1 return, %Ret_Val% } ;//Is multiplying FirstLongString and SecondLongString LongIntStringMult(FirstLongString,SecondLongString) { local ResultString, MulRes, RightVal, LeftVal, Loop1Count, OutLoopCounter local Loop2Count, InLoopCounter, ABSCompi, Help, ZeroAdd, FIsNeg, SIsNeg ;//remember the minus FIsNeg:=IsNeg(FirstLongString) SIsNeg:=IsNeg(SecondLongString) ;//remove the minus on workstrings WS1:=ABSLongIntString(FirstLongString) WS2:=ABSLongIntString(SecondLongString) ;//compare absolute size of BigNums ABSCompi:=CompareLongintStrings(WS1,WS2,0) if (ABSCompi=1) ;//We do BiggerNum * SmallerNum Swap_Values(WS1,WS2) StringLen, Loop1Count, WS1 StringLen, Loop2Count, WS2 OutLoopCounter=0 loop, %Loop1Count% { OutLoopCounter+=1 Help = Rem = 0 InLoopCounter=0 loop, %loop2Count% { InLoopCounter+=1 RightVal:=StringGetChar(WS2,InLoopCounter,R) LeftVal:=StringGetChar(WS1,OutLoopCounter,R) MulRes:=(LeftVal*RightVal)+rem rem:=Div(Mulres,10) Rest:=Mod(Mulres,10) Help=%Rest%%Help% } Help=%rem%%Help% ;/Not sure if thies right ??? ZeroAdd:=OutLoopCounter-1 loop, %ZeroAdd% Help=%Help%0 MakeFitLength(ResultString,Help) ResultString:=ABSLongIntStringAdd(ResultString,Help) } RemoveLeadingZeros(ResultString) If ((FIsNeg="1") and (SIsNeg="0")) or ((FIsNeg="0") and (SIsNeg="1")) return, -%Resultstring% else return, %Resultstring% } ButtonCompare: Gui, Submit, NoHide CompareLongIntStrings(Long1,Long2,1) ;//Both are written back without leading zeros GuiControl,,Long1,%Long1% GuiControl,,Long2,%Long2% return ButtonSwap: Gui, Submit, NoHide Swap_Values(Long1,Long2) GuiControl,,Long1,%Long1% GuiControl,,Long2,%Long2% return PM1: Gui, Submit, NoHide if (IsNeg(Long1)="1") { Long1:=ABSLongintString(Long1) GuiControl,,Long1,%Long1% } else GuiControl,,Long1,-%Long1% return PM2: Gui, Submit, NoHide if (IsNeg(Long2)="1") { Long2:=ABSLongintString(Long2) GuiControl,,Long2,%Long2% } else GuiControl,,Long2,-%Long2% return ButtonB1+B2: Gui, Submit, NoHide Summy:=LongIntStringAdd(Long1,Long2) GuiControl,, ResultEdit, %Summy%`n`nHopefully the result is OK :) return ButtonB1-B2: Gui, Submit, NoHide Summy:=LongIntStringSub(Long1,Long2) GuiControl,, ResultEdit, %Summy%`n`nHopefully the result is OK :) return ButtonB1*B2: Gui, Submit, NoHide Summy:=LongIntStringMult(Long1,Long2) GuiControl,, ResultEdit, %Summy%`n`nHopefully the result is OK :) return ButtonB1/B2: MsgBox, Are you crazy ?`nThe Result mostly will be a float`n`nOk, I will work on this later :) return
Greetings From Rubberduck