Nice one, but if trying to use a precision higher than 6 it crashes.
See my implementation, using Pow slows things down a bit but not too much and you get rid of the array.
StrF2 has a issue with rounding though.
StrF3 behaves very closely to the original StrF but only up to around a precision of 6.
StrF can easily be tweaked to handle high numbers and very high precision (like 10 decimals after the . ) if you simply change all .l to .q
However any speed gains are lost as the original StrD is just as fast,
actually it seems that StrF and StrD are similar in speed, so if accuracy is wanted then StrD would be my advice.
If you know more or less what the input will be then it's not that hard to make speedier variants of PB's routines, but if you do not know what the input can be then you will find that PB's routines are much safer to use.
Apparently Fred knows his stuff 
Code: Select all
EnableExplicit
DisableDebugger
Procedure.s StrD3(a.d,precision.l=6) ;Accurate up to a max precision of ?
 Protected i.l,temp$,precmul.q,result$,n.q
 If precision
  precmul=Pow(10,precision)
  If a=0.0
   result$=RSet("0.",precmul,"0")
  Else
   n=a*precmul
   temp$=StrQ(n)
   result$=Left(temp$,Len(temp$)-precision)+"."+Right(temp$,precision)
  EndIf
 Else
  If Not a
   result$="0"
  Else
   result$=Str(a)
  EndIf
 EndIf
 ProcedureReturn result$
EndProcedure
Procedure.s StrF3(a.f,precision.l=6) ;Accurate up to a max precision of 6
 Protected i.l,temp$,precmul.l,result$,n.l
 If precision
  precmul=Pow(10,precision)
  If a=0.0
   result$=RSet("0.",precmul,"0")
  Else
   n=a*precmul
   temp$=Str(n)
   result$=Left(temp$,Len(temp$)-precision)+"."+Right(temp$,precision)
  EndIf
 Else
  If Not a
   result$="0"
  Else
   result$=Str(a)
  EndIf
 EndIf
 ProcedureReturn result$
EndProcedure
Procedure.s StrF2(a.f,precision.l=6) ;Fast but has additional rounding errors compared to original?
  Protected i.l,temp$,minus.l,result.l
  precision=Pow(10,precision) ;Pow is used to avoid crash issue with higher precisions
  If a<0
    minus=1
    a=-a
  EndIf
  i=a
  If a<i
    i-1
  EndIf
  temp$=Str(((a - i)*precision)+precision)
  If minus
    If precision>0
      ProcedureReturn "-"+Str(i)+"."+Right(temp$,Len(temp$)-1)
    Else
      ProcedureReturn "-"+Str(i)
    EndIf
  Else
    If precision>0
      ProcedureReturn Str(i)+"."+Right(temp$,Len(temp$)-1)
    Else
      ProcedureReturn Str(i)
    EndIf
  EndIf
EndProcedure
#Tries = 500000
Define test$,i.l,time.l
time = GetTickCount_()
For i = 0 To #Tries
  test$=StrF(-1234.5678910,6)
Next
MessageRequester("", Str(GetTickCount_()-time)+" "+test$)
time = GetTickCount_()
For i = 0 To #Tries
  test$=StrF2(-1234.5678910,6)
Next
MessageRequester("", Str(GetTickCount_()-time)+" "+test$)
time = GetTickCount_()
For i = 0 To #Tries
  test$=StrF3(-1234.5678910,6)
Next
MessageRequester("", Str(GetTickCount_()-time)+" "+test$)
time = GetTickCount_()
For i = 0 To #Tries
  test$=StrD3(-1234.5678910,6)
Next
MessageRequester("", Str(GetTickCount_()-time)+" "+test$)
time = GetTickCount_()
For i = 0 To #Tries
  test$=StrD(-1234.5678910,6)
Next
MessageRequester("", Str(GetTickCount_()-time)+" "+test$)