Page 1 of 1

Floats increment accuracy

Posted: Thu Dec 02, 2010 7:17 pm
by djes
It doesn't seem a normal behaviour to me. Try this code with debugger enabled.

Code: Select all

i.f = 2047.9
Repeat
  Debug i
  i + 0.0001
ForEver
End
I know float limits... Anyway, it's strange !

Re: .f add problem

Posted: Thu Dec 02, 2010 9:09 pm
by STARGÅTE
I know float limits...
so, no Bug!

float increment : http://www.purebasic.fr/german/viewtopi ... =8&t=23364

so:

Code: Select all

Procedure.f IncF(Value.f)
  Protected *Long.Long = @Value
  If Not IsNAN(Value)
    If Value > 0
      If Not IsInfinity(Value)
        *Long\l + 1
      EndIf
    ElseIf Value < 0
      *Long\l - 1
    Else
      *Long\l = 1
    EndIf
  EndIf
  ProcedureReturn Value
EndProcedure

i.f = 2048
Debug i
Debug IncF(i)
the next is worth after 2048.0 is 2048.000244140625
The difference is: 0.00024... (> 0.0001 * 2)
so, no increment with 0.0001

Re: .f add problem

Posted: Thu Dec 02, 2010 10:09 pm
by djes
Thank you very much for these great codes, STARGÅTE ! Anyway, it hurted me when I saw that I cannot add 0.0001 to 2048 :/ . I'd like to have an example to how to handle this, without using doubles :D

Re: .f add problem

Posted: Thu Dec 02, 2010 10:47 pm
by Trond
djes wrote:Thank you very much for these great codes, STARGÅTE ! Anyway, it hurted me when I saw that I cannot add 0.0001 to 2048 :/ . I'd like to have an example to how to handle this, without using doubles :D
You have to use doubles.

Re: .f add problem

Posted: Thu Dec 02, 2010 11:53 pm
by djes
Trond wrote:
djes wrote:Thank you very much for these great codes, STARGÅTE ! Anyway, it hurted me when I saw that I cannot add 0.0001 to 2048 :/ . I'd like to have an example to how to handle this, without using doubles :D
You have to use doubles.
Don't know why, but I'm sure you'll regret to have spoken so fast. :mrgreen:

Re: .f add problem

Posted: Fri Dec 03, 2010 12:17 pm
by djes
I'll make a code

Re: .f add problem

Posted: Fri Dec 03, 2010 12:18 pm
by Trond
djes wrote:
Trond wrote:
djes wrote:Thank you very much for these great codes, STARGÅTE ! Anyway, it hurted me when I saw that I cannot add 0.0001 to 2048 :/ . I'd like to have an example to how to handle this, without using doubles :D
You have to use doubles.
Don't know why, but I'm sure you'll regret to have spoken so fast. :mrgreen:
Right, I forgot you can use long doubles (10 bytes) with inline asm.

Re: .f add problem

Posted: Fri Dec 03, 2010 12:20 pm
by djes
Thanks to Regenduft code and Stargate help, here something giving a clue on what can be added to a float depending on range.

Code: Select all

;****************************************************************************
;*
;* Minimal increment value 
;* Show floating point accuracy depending on range
;* djes 12/3/2010
;* based on Regenduft's code
;*

;****************************************************************************
;* IncF by Regenduft
;* http://www.purebasic.fr/german/viewtopic.php?f=8&t=23364
;*
;* >= Value to increment by the minimal floating point possible
;* => incremented value
;*
Procedure.f IncF(Value.f)
  Protected *l.Long = @Value
  
  If *l\l & $7F800000 <> $7F800000 Or *l\l & $7FFFFF = 0 ; IsNAN(Value)=0 <- Geschwindigkeitsoptimierung
    
    ; positive Float inkrementieren
    If Value > 0
      If *l\l < $7F800000 ; IsInfinity(Value)=0 <- Geschwindigkeitsoptimierung
        *l\l + 1
      EndIf
    
    ; negative Float inkrementieren
    ElseIf Value < 0
      *l\l - 1
    
    ; Null-Float inkrementieren
    Else
      *l\l = 1
    EndIf
    
  EndIf
  
  ProcedureReturn Value
EndProcedure

;****************************************************************************
;- MAIN

OpenConsole()
EnableGraphicalConsole(1)

MinDiff1.f = 0
MinDiff2.f = 0
ConsoleLine = 1

For u = 0 To $7FFFFFFF Step 1
  
  ConsoleLocate(0, 0)
  Print(RSet(Str(u), 10))
  
  i1.f = u
  Diff.f = IncF(i1) - i1
  If Diff > MinDiff1
    MinDiff1 = Diff
    ConsoleLocate(0, ConsoleLine)
    PrintN("New min increment value found : at " + RSet(Str(i1), 10) + " -> " + RSet(StrF(MinDiff1), 10))
    ConsoleLine + 1
  EndIf
  
  i2.f = 0-u
  Diff.f = IncF(i2) - i2
  If Diff > MinDiff2
    MinDiff2 = Diff
    ConsoleLocate(0, ConsoleLine)
    PrintN("New min increment value found : at " + RSet(Str(i2), 10) + " -> " + RSet(StrF(MinDiff2), 10))
    ConsoleLine + 1
  EndIf
  
Next u

Re: Floats increment accuracy

Posted: Fri Dec 03, 2010 3:04 pm
by STARGÅTE
code is not from me, its from Regenduft :wink:

Re: Floats increment accuracy

Posted: Fri Dec 03, 2010 3:55 pm
by djes
Ok!