Request: Double data types

Blitz3D Forums/Blitz3D Bug Reports/Request: Double data types

The Forum Archive is locked. These are the original blitzbasic.com forums, kept so their posts can still be read and searched. No new topics, replies or edits can be made here. To join the conversation, head over to the Blitz3D+ forums.

Hey there Mark, here is a little something I did. I got my own version of the FloatFraction running in there which is a very optimized version of one of your early tries. I got a performance bench and a trial error test also. Enjoy!
Local rounding_scale# = 5000.0
scale% = 1000000
;Goto precision_test

.performance_test
printsync "*************** Performance test ***************"
printsync ""
SeedRnd 1
printsync "Calculating leadoff time..."
Local m% = MilliSecs()
For count = 1 To scale
   value# = Rnd(-rounding_scale, rounding_scale)
Next
Local leadoff% = (MilliSecs() - m)
Print ""

SeedRnd 1
printsync "Running first iteration..."
m = MilliSecs()
For count = 1 To scale
   value# = Rnd(-rounding_scale, rounding_scale)
   test# = FloatFraction_33(value)
Next
final% = (MilliSecs() - m) - leadoff
Print "Time used (minus " + leadoff + "ms leadoff): " + final + "ms"
Print ""

SeedRnd 1
printsync "Running second iteration..."
m = MilliSecs()
For count = 1 To scale
   value# = Rnd(-rounding_scale, rounding_scale)
   test# = FloatFraction_markcw(value)
Next
final% = (MilliSecs() - m) - leadoff
Print "Time used (minus " + leadoff + "ms leadoff): " + final + "ms"
Print ""

.precision_test
printsync "**************** Precision test ****************"
printsync ""

Local errors%

printsync "Running first iteration..."
errors = 0

SeedRnd 1
For count = 1 To scale
   value# = Rnd(-rounding_scale, rounding_scale)
   s$ = Str(value#)
   pos = Instr(s$, ".", 1)
   compare$ = "0" + Right(s$, Len(s$) - pos + 1)
   fraction# = FloatFraction_33(value#)
   If compare$ <> Str(fraction#)
;      Print "value# = " + value# + ", fraction# = " + fraction#
      errors = errors + 1
   EndIf
Next
Print "" + errors + " irregularities on " + (count - 1) + " tries"
Print ""


printsync "Running second iteration..."
errors = 0

SeedRnd 1
For count = 1 To scale
   value# = Rnd(-rounding_scale, rounding_scale)
   s$ = Str(value#)
   pos = Instr(s$, ".", 1)
   compare$ = "0" + Right(s$, Len(s$) - pos + 1)
   fraction# = FloatFraction_markcw(value#)
   If compare$ <> Str(fraction#)
;      Print "value# = " + value# + ", fraction# = " + fraction#
      errors = errors + 1
   EndIf
Next
Print "" + errors + " irregularities on " + (count - 1) + " tries"
Print ""

Print "press any key"
WaitKey()
End


Function printsync(txt$)
   Print txt$
   Delay 100
End Function

; **************** The contenders ****************

Function FloatFraction_33#(Value#)
   ;Returns the fractional part of a float as a float
   ;The whole part and sign are removed
   Local WholePart%, e#, fraction#, test#, Whole#
   If Value < 0 Then Value = -Value
   Whole# = Floor(Value)
   test# = 1 ;Work out the number of whole places
   For WholePart = 0 To 6
      If test > Whole Then Exit
      test = test * 10
   Next
   If WholePart > 5 Then
      Return 0 ;Out of range, so no fraction
   Else
      e# = Exp10(6 - WholePart) ;Floats only have 6 meaningful places
      fraction# = Int(Value * e - Whole * e) / e
      If fraction >= 1.0 Then
         Return fraction - 1.0
      Else
         Return fraction
      EndIf
   EndIf
End Function

Function Exp10#(value%) ; about 8 times faster than 10^value
   Select value
      Case 0 : Return 1.0          ; 10^0
      Case 1 : Return 10.0         ; 10^1
      Case 2 : Return 100.0        ; 10^2
      Case 3 : Return 1000.0       ; 10^3
      Case 4 : Return 10000.0      ; 10^4
      Case 5 : Return 100000.0     ; 10^5
      Case 6 : Return 1000000.0    ; 10^6
      Case 7 : Return 10000000.0   ; 10^7
      Case 8 : Return 100000000.0  ; 10^8
      Case 9 : Return 1000000000.0 ; 10^9
   End Select
End Function



Function FloatFraction_markcw#(Value#)
;Returns the fractional part of a float as a float
;The whole part and sign are removed

   Local Temp#, Loop, WholePart, Round#, FractionPart
   Local RoundPart, Pow#, Real, Fraction, Check#, CheckPart

   Temp# = 0.1 ;Work out the number of whole places
   For Loop = 1 To 45
      If Temp# * 10 => Abs(Value#) Then Exit
      Temp# = Temp# * 10
      WholePart = WholePart + 1
   Next

   Temp# = Abs(Value#) ;Work out the number of fractional places
   For Loop = 1 To 45
      If Temp# - Floor(Temp#) <= 0 Then Exit
      Round# = Temp#
      Temp# = Temp# * 10
      FractionPart = FractionPart + 1
   Next

   RoundPart = FractionPart
   If FractionPart + WholePart > 6 And WholePart > 0
      FractionPart = 6 - WholePart ;Floats only have 6 meaningful places
   EndIf

   Temp# = Abs(Value#) ;Calculate fraction
   Pow# = (10 ^ FractionPart)
   Real = (Temp# * Pow#)
   Fraction = Real - (Floor(Temp#) * Pow#)

   Check# = Temp# - Floor(Temp#) ;Work out number of fractional places
   For Loop = 1 To 45
      If Check# - Floor(Check#) <= 0 Then Exit
      Check# = Check# * 10
      CheckPart = CheckPart + 1
   Next

   If Temp# <> Real / Pow# ;Special error checks, don't ask
      If Temp# = Round# / Pow#
         If Int(Round# + 0.001) > Int(Round#)
            If CheckPart = RoundPart
               Fraction = Fraction + 1 ;Round up
            EndIf
         EndIf
      EndIf
   EndIf

   If WholePart > 5 Then Fraction = 0 ;Out of range
   If Fraction / Pow# >= 1.0 Then Fraction = 0 ;Severe rounding error
   Return Fraction / Pow#
End Function