Page 1 of 1

SOLVED - Why doesn't this work (round a float via a procedure) ???

Posted: Sun Jul 14, 2024 10:36 am
by Martt
Hi,

I do not understand why the following code returns #True, since it should be #False.
Not using the procedure and using a manual Round function works fine.
But this should work imho...

Hmm, Asm compiler (x86 and x64) returns #True, but C compiler (x86 and x64) returns #False). Strange.

Code: Select all

EnableExplicit

Structure Rectangle
    x.f
    y.f
    width.f
    height.f
EndStructure

Procedure.i RectangleRound(*Inout.Rectangle)

    If *Inout
        *Inout\x      = Round(*Inout\x, #PB_Round_Nearest)
        *Inout\y      = Round(*Inout\y, #PB_Round_Nearest)
        *Inout\width  = Round(*Inout\width, #PB_Round_Nearest)
        *Inout\height = Round(*Inout\height, #PB_Round_Nearest)
    EndIf

    ProcedureReturn *Inout

EndProcedure

Define Bounds.Rectangle

RectangleRound(@Bounds)
;Round(Bounds\x, #PB_Round_Nearest)
;Round(Bounds\y, #PB_Round_Nearest)

If Bounds\x And Bounds\y
    Debug "#True"
Else
    Debug "#False"
EndIf


Re: Why doesn't this work (round a float via a procedure) ???

Posted: Sun Jul 14, 2024 10:54 am
by infratec
A float is not an expression.

You can do it like this:

Code: Select all

If Int(Bounds\x) And Int(Bounds\y)
Or like this (better solution)

Code: Select all

If Bounds\x <> 0 And Bounds\y <> 0

Re: Why doesn't this work (round a float via a procedure) ???

Posted: Sun Jul 14, 2024 11:03 am
by Martt
infratec wrote: Sun Jul 14, 2024 10:54 am A float is not an expression.

You can do it like this:

Code: Select all

If Int(Bounds\x) And Int(Bounds\y)
Or like this (better solution)

Code: Select all

If Bounds\x <> 0 And Bounds\y <> 0
I know that <> #Null works fine. But If with a zero number should always return False. I'm using that all the time, never fails. And the C compiler does return #False in my example.

Code: Select all

Define A.f = 0.0

If A
    Debug "#True"
Else
    Debug "#False"
EndIf

Re: Why doesn't this work (round a float via a procedure) ???

Posted: Sun Jul 14, 2024 11:17 am
by mk-soft
Always ??? :mrgreen:

Float or double values on is the same to evaluate is always bad

Code: Select all

Define A.f = 0.0

Debug PeekL(@a)

If A
    Debug "#True"
Else
    Debug "#False"
EndIf

Define A.f = -0.0

Debug PeekL(@a)

If A
    Debug "#True"
Else
    Debug "#False"
EndIf

Re: Why doesn't this work (round a float via a procedure) ???

Posted: Sun Jul 14, 2024 11:42 am
by Little John
To get to the point:

Code: Select all

; tested with PB 6.04 LTS (x64) on Windows (ASM backend)

Define A.f = -0.0

If A              ; wrong
   Debug "True"
Else
   Debug "False"
EndIf

If A <> 0         ; correct
   Debug "True"
Else
   Debug "False"
EndIf

Re: Why doesn't this work (round a float via a procedure) ???

Posted: Sun Jul 14, 2024 11:49 am
by SMaag
It's again the genearal problem with Floats

it's generally not allowed to use floats as an expression! Would be better the compiler would not allow that!

A short time ago I went deeper into that issue.
If you do like that you might get a different result on different compilers and a different result with same compiler
on different CPU's. If you search at google you will find some articels about that problem.
Until today you will not get a compaerable result up tp the last digit with floats on different CPU's!

1. If you want to compare two floats for equal you have to use an interval!
2. Never use floats as expression like it is possible with Int

The difference betwwen PB ASM-Compiler and C-Compiler is:
PB ASM always use the Float unit (80 Bit) the C-Compilers optimize some float options and use faster MMX or SSE Version
and at MMX SSE a float is only 64-Bit.

That issue is causing some more problems in PB.
If you use an Int with >= 48Bit and do an ABS() you will get differnt results in ASM and C too.
ASM use FloatUnit ABS command and C-Compiler use MMX/SEE what cause a rounding Problem.
Under ASM you get the right value and C is wrong!


The ABS() Problem
https://www.purebasic.fr/english/viewto ... 53#p614053

Floating Point Determinism
https://gafferongames.com/post/floating ... terminism/

Re: Why doesn't this work (round a float via a procedure) ???

Posted: Sun Jul 14, 2024 12:40 pm
by Martt
Ok, thanks for the explanations, everybody. Looks like I picked up a bad habit along the way.

In this case it kind of sucks, since I'm working on a RayLib program, and RayLib uses floats everywhere.
It's only 40K lines to check. Search If....... I need a drink.... :oops: :evil: