I have a question to testers, at the end of the code I use an example from the help file for COMMAND.
No matter how I define compiler options, whether by code (as here) or by command line, I cannot see my options from COMMAND()
If no options, then it takes about a second, with speed optimizations (02 or O3) it takes less than half a second for 5000 decimal places, so the optimizations will be noticed.
Code: Select all
#cmdline "-v -gen gcc -Wc -O2"
#include "crt/stdio.bi" 'for printf for those using win 11 terminal
Function plus(Byval _num1 As String,Byval _num2 As String) As String
Static As Const Ubyte addQmod(0 To 19)={48,49,50,51,52,53,54,55,56,57,48,49,50,51,52,53,54,55,56,57}
Static As Const Ubyte addbool(0 To 19)={0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1}
Var n_=0
Dim As Ubyte addup=Any,addcarry=Any
#macro finish()
answer=Ltrim(answer,"0")
Return answer
#endmacro
If Len(_num2)>Len(_num1) Then
Swap _num2,_num1
End If
Var diff=Len(_num1)-Len(_num2)
Dim as string answer="0"+_num1
addcarry=0
For n_=Len(_num1)-1 To diff Step -1
addup=_num2[n_-diff]+_num1[n_]-96
answer[n_+1]=ADDQmod(addup+addcarry)
addcarry=ADDbool(addup+addcarry)
Next n_
If addcarry=0 Then
finish()
End If
If n_=-1 Then
answer[0]=addcarry+48
finish()
Endif
For n_=n_ To 0 Step -1
addup=_num1[n_]-48
answer[n_+1]=ADDQmod(addup+addcarry)
addcarry=ADDbool(addup+addcarry)
If addcarry=0 Then Exit For
Next n_
answer[0]=addcarry+48
finish()
End Function
Function minus(Byval num1 As String,Byval num2 As String) As String
Static As Const Ubyte subQmod(0 To 19)={48,49,50,51,52,53,54,55,56,57,48,49,50,51,52,53,54,55,56,57}
Static As Const Ubyte subBool(0 To 19)={1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0}
Dim As Integer bigger =Any
Dim sign As String
Var lenf=Len(NUM1)
Var lens=Len(NUM2)
#macro finishup()
answer=Ltrim(answer,"0")
If answer="" Then Return "0"
Return sign+answer
#endmacro
#macro compare()
Do
If Lens>lenf Then bigger= -1:Exit Do
If Lens<lenf Then bigger =0:Exit Do
If NUM2>NUM1 Then
bigger=-1
Else
bigger= 0
End If
Exit Do
Loop
#endmacro
compare()
If bigger Then
sign="-"
Swap NUM2,NUM1
Swap lens,lenf
End If
Var diff=lenf-lens
Dim As String answer=NUM1
Dim As Integer n=Any
Dim As Ubyte takeaway=Any,subtractcarry=Any
subtractcarry=0
For n=lenf-1 To diff Step -1
takeaway= num1[n]-num2[n-diff]+10-subtractcarry
answer[n]=Subqmod(takeaway)
subtractcarry=Subbool(takeaway)
Next n
If subtractcarry=0 Then:finishup():End If
If n=-1 Then:finishup():End If
For n=n To 0 Step -1
takeaway= num1[n]-38-subtractcarry
answer[n]=Subqmod(takeaway)
subtractcarry=Subbool(takeaway)
If subtractcarry=0 Then Exit For
Next n
finishup()
End Function
Function smult(n As String,d As Long) As String 'multiply n by a single digit
Static As Ubyte _mod(99)= _
{48,49,50,51,52,53,54,55,56,57,48,49,50,51,52,53,54,55,56,57,48,49,50,51,52,53,54,55,56,57,48, _
49,50,51,52,53,54,55,56,57,48,49,50,51,52,53,54,55,56,57,48,49,50,51,52,53,54,55,56,57,48, _
49,50,51,52,53,54,55,56,57,48,49,50,51,52,53,54,55,56,57,48,49,50,51,52,53,54,55,56,57,48, _
49,50,51,52,53,54,55,56,57}
Static As Ubyte _div(99)= _
{0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3, _
3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,6, _
6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,8,9, _
9,9,9,9,9,9,9,9,9}
Dim As String ans=String(Len(n)+1,0)
Dim As Ubyte carry,main,temp
For z As Integer=Len(n)-1 To 0 Step -1
temp=(d)*(n[z]-48)+carry
main=_mod(temp)
carry=temp\10
'carry=_div(temp)'temp\10 'alternate
ans[z+1]=main
Next z
ans[0]=carry+48
Return Iif(Len(Ltrim(ans,"0")),Ltrim(ans,"0"),"0")
End Function
Function isbigger(n1 As String,n2 As String) As Long 'is n1>n2
Dim As Long lenn1=Len(n1),lenn2=Len(n2)
#macro hide
If Len(n1)>Len(n2) Then Return -1
If Len(n1)<Len(n2) Then Return 0
#endmacro
'hide
If Lenn1>Lenn2 Then Return -1
If Lenn1<Lenn2 Then Return 0
If n1>n2 Then
Return -1
Else
Return 0
End If
End Function
Function bmult(Byval a As String,Byval b As String,flag As Long=0) As String
Static As Ubyte _mod(99)= _
{48,49,50,51,52,53,54,55,56,57,48,49,50,51,52,53,54,55,56,57,48,49,50,51,52,53,54,55,56,57,48, _
49,50,51,52,53,54,55,56,57,48,49,50,51,52,53,54,55,56,57,48,49,50,51,52,53,54,55,56,57,48, _
49,50,51,52,53,54,55,56,57,48,49,50,51,52,53,54,55,56,57,48,49,50,51,52,53,54,55,56,57,48, _
49,50,51,52,53,54,55,56,57}
Static As Ubyte _div(99)= _
{0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3, _
3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,6, _
6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,8,9, _
9,9,9,9,9,9,9,9,9}
Var la = Len(a),lb = Len(b)
If Len(b)>Len(a) Then Swap a,b:Swap la,lb
Dim As Ubyte n=Any,carry=Any,ai=Any
Dim as string c =String(la+lb,"0")
For i As Integer =la-1 To 0 Step -1
carry=0:ai=a[i]-48
For j As Integer =lb-1 To 0 Step -1
n = ai * (b[j]-48) + (c[i+j+1]-48) + carry
carry =_Div(n):c[i+j+1]=_Mod(n)
Next j
c[i]+=carry
Next i
If Ltrim(c,"0")="" Then Return "0"
If flag=1 Then Return c Else Return Ltrim(c,"0")
End Function
Sub _Remove(Text As String,Char As String)
Var index = 0,asci=Asc(char)
For i As Integer = 0 To Len(Text) - 1
If Text[i] <> asci Then Text[index] = Text[i] : index =index+ 1
Next : Text = Left(Text,index)
End Sub
Sub _split(stri As String,char As String,var1 As String,var2 As String)
Dim As Integer pst=Instr(stri,char)
var1="":var2=""
If pst<>0 Then
var1=Mid(stri,1,pst-1)
var2=Mid(stri,pst+1)
Else
var1=stri
End If
End Sub
Sub insert(s As String,char As String=".",position As Long)
If position>0 And position<=Len(s) Then
Dim As String part1=Mid(s,1,position-1)
Dim As String part2=Mid(s,position)
s=part1+char+part2
End If
End Sub
Function fmult(Byval a As String,Byval b As String) As String
Dim As String sign
If Instr(a,"-") xor Instr(b,"-") Then
_remove(a,"-")
_remove(b,"-")
sign="-"
End If
If Instr(a,"-") And Instr(b,"-") Then
_remove(a,"-")
_remove(b,"-")
sign=""
End If
Dim As String var1,var2
_split(a,".",var1,var2)
Dim As Integer lendec1=Len(var2)
_split(b,".",var1,var2)
Dim As Integer lendec2=Len(var2)
_remove(a,".")
_remove(b,".")
Dim As String ans=bmult(a,b,1)
insert(ans,".",Len(ans)-(lendec1+lendec2)+1)
Return sign+Ltrim(ans,"0")
End Function
Function bigSQR(st As String,pl As Integer) As String
Dim As String var1,var2,p1',p2
Dim As Integer j=Any,tr
#macro split(stri,var1)
For j=0 To Len(stri)-1
If tr=0 And stri[j]<>46 Then
var1=var1+Chr(stri[j])
End If
If stri[j]=46 Then tr=1
Next j
tr=0
#endmacro
If Instr(st,"-")<>0 Then Return " 1.#QNAN"
Dim s As String=st
Dim cp1 As String
split(s,p1) 'p1=number part
Dim As Integer lenp1=Len(p1)
Dim As String pair,div,num,mult,diff,temp,olddiv,digit
Static As String cd(0 To 10)
Dim As Integer d=Any,count,divflag=Any,k=Any,p,endrun=Any,index,c=1
For i As Integer = 0 To Len(s) - 1 'remove decimal .
If s[i] <> 46 Then s[index] = s[i] : index =index+ 1
Next : s = Left(s,index)
If (Lenp1+1+1) Mod 2 =0 Then p=2 Else p=1
s=s+String(2*pl,"0")
Dim decflag As Integer
If p1="" Then
decflag=1
temp=temp+"."
End If
endrun=Lenp1+2*pl
Dim As Long bg
Do
pair=Mid(s,c,p)
num=Ltrim(num+pair,"0")
divflag=0
Dim As String sd
For d=0 To 9
sd=Str(d)
digit=sd:k=1
count=count+1
If divflag=0 Then div=olddiv+sd
mult=smult(div,d)
bg=isbigger(num,mult)
diff=minus((num),mult): cd(count)=diff
If diff[0]=48 Then
digit=sd
k=1
Exit For
End If
If diff[0]=45 Then
divflag=1
digit=Str(d-1)
div=olddiv+digit
k=0
Exit For
End If
Next d
div=plus(div,digit)
olddiv=div
num=cd(count-1+k)
temp=temp+digit
If decflag=0 Then
cp1=cp1+pair
If cp1=p1 Then
temp=temp+"."
End If
End If
count=0
k=1
c=c+p
p=2
Loop Until c>=endrun
Return temp
End Function
Dim As Double t=Timer
Dim As String number=".000000000000000000000000000000123456789"'some positive number
Dim As String sq= bigSQR(number,5000)
Dim As Double t2=Timer
Color 15
Printf( sq+!"\n") 'incase you are using win 11 terminal
Color 3
Print t2-t,"seconds",Len(Mid(sq,1+Instr(sq,".")));" decimal places"
Color 15
Print "check original and sqr*sqr"
Print number
printf(Left(fmult(sq,sq),200)+" . . ."+!"\n")
Print
'FROM HELPFILE FOR COMMAND
Print "program launched via: " & Command(0)
Dim As Long i = 1
Do
Dim As String arg = Command(i)
If Len(arg) = 0 Then
Exit Do
End If
Print "command line argument " & i & " = """ & arg & """"
i += 1
Loop
If i = 1 Then
Print "(no command line arguments)"
End If
Print "Done . . ."
Sleep