If, Bool - rounded Floats

Everything else that doesn't fall into one of the other PB categories.
User avatar
Josh
Addict
Addict
Posts: 1183
Joined: Sat Feb 13, 2010 3:45 pm

If, Bool - rounded Floats

Post by Josh »

Can anyone explain why the evaluation of If and Bool float values are rounded?

For me, zero is #False and everything else is #True

Code: Select all

Debug Bool (Not 0.4)
Debug Bool (Not 0.5)

If 1.0/2
  Debug "#True"
Else
  Debug "#False"
EndIf

If 1.0/3
  Debug "#True"
Else
  Debug "#False"
EndIf
sorry for my bad english
User avatar
skywalk
Addict
Addict
Posts: 3997
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: If, Bool - rounded Floats

Post by skywalk »

I am sort of confused?

Code: Select all

Define.d x,y
Define.i ix,iy
x = 1.0 / 2
y = 1.0 / 3
Debug "-- Doubles assigned a Double --"
If x
  Debug "F:1/2    = True"
Else
  Debug "F:1/2    = False"
EndIf
If Bool(x)
  Debug "BF:1/2   = True"
Else
  Debug "BF:1/2   = False"
EndIf
If y
  Debug "F:1/3    = True"
Else
  Debug "F:1/3    = False"
EndIf
If Bool(y)
  Debug "BF:1/3   = True"
Else
  Debug "BF:1/3   = False"
EndIf
Debug "-- Integers assigned a Double --"
ix = 1.0 / 2
iy = 1.0 / 3
If ix
  Debug "I:1.0/2  = True"
Else
  Debug "I:1.0/2  = False"
EndIf
If Bool(ix)
  Debug "BI:1.0/2 = True"
Else
  Debug "BI:1.0/2 = False"
EndIf
If iy
  Debug "I:1.0/3  = True"
Else
  Debug "I:1.0/3  = False"
EndIf
If Bool(iy)
  Debug "BI:1.0/3 = True"
Else
  Debug "BI:1.0/3 = False"
EndIf
Debug "-- Integers assigned an Integer --"
ix = 1 / 2
iy = 1 / 3
If ix
  Debug "I:1/2    = True"
Else
  Debug "I:1/2    = False"
EndIf
If Bool(ix)
  Debug "BI:1/2   = True"
Else
  Debug "BI:1/2   = False"
EndIf
If iy
  Debug "I:1/3    = True"
Else
  Debug "I:1/3    = False"
EndIf
If Bool(iy)
  Debug "BI:1/3   = True"
Else
  Debug "BI:1/3   = False"
EndIf
; -- Doubles assigned a Double --
; F:1/2    = True
; BF:1/2   = True
; F:1/3    = True
; BF:1/3   = True
; -- Integers assigned a Double --
; I:1.0/2  = True
; BI:1.0/2 = True
; I:1.0/3  = False
; BI:1.0/3 = False
; -- Integers assigned an Integer --
; I:1/2    = False
; BI:1/2   = False
; I:1/3    = False
; BI:1/3   = False
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
User avatar
spikey
Enthusiast
Enthusiast
Posts: 586
Joined: Wed Sep 22, 2010 1:17 pm
Location: United Kingdom

Re: If, Bool - rounded Floats

Post by spikey »

Josh wrote:For me, zero is #False and everything else is #True
No, strictly speaking, in Boolean algebra True is True and False is False, and neither is a number. But when programming, just like integers and floats these values get 'cast' into binary which can be stored in a register.
Josh wrote:Can anyone explain why the evaluation of If and Bool float values are rounded?
Think about each part of the statement individually as language not code - there's an underlying logic error.

Bool - make a true/false determination
Not - on the result of the true/false inversion
0.4 - of a continuous value.

In real world logic this makes no sense. Don't think of 0.4 as a discrete value - it isn't, its 0.40000000000000000000000......

However the compiler has a set of optimisation rules that it follows, and one of these is an implicit cast which says 'if you are put in a situation where a continuous variable is supplied as the operand of a function expecting discrete values - round it according to these rules'.
What the rule doesn't say is 'unless boolean functions are involved somewhere else'.

So the resulting program:
makes a true/false determination
on the result of the logical inversion
of a continuous value rounded according to the rules.

In C++ compilers you'd probably get an error or a warning about not using an explicit cast. This is one of those situations where the 'GIGO' rule applies.
User avatar
spikey
Enthusiast
Enthusiast
Posts: 586
Joined: Wed Sep 22, 2010 1:17 pm
Location: United Kingdom

Re: If, Bool - rounded Floats

Post by spikey »

skywalk wrote:I am sort of confused?
This one is more difficult to explain but the problem stems from a similar root cause - falling foul of casting.

To see how it comes about you have to look at the resulting assembler. In the first group the compiler elects for floating point instructions on floating point data values, unsurprisingly. However in the second and third groups it elects for integer instructions on integer data. However the integers selected for assignment differ from the second to third groups.

You'd need to look at the compiler's source code to be definitive but I'd guess this is because a different implicit cast rule in the compiler gets invoked in the second group compared with the third and there is a slight discrepency in the corresponding output.

Code: Select all

; Debug "-- Integers assigned a Double --"
; ix = 1.0 / 2
  MOV    qword [v_ix],1
; iy = 1.0 / 3
  MOV    qword [v_iy],0

; Debug "-- Integers assigned an Integer --"
; ix = 1 / 2
  MOV    qword [v_ix],0
; iy = 1 / 3
  MOV    qword [v_iy],0
User avatar
skywalk
Addict
Addict
Posts: 3997
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: If, Bool - rounded Floats

Post by skywalk »

Thanks, I did not consider the ASM. This lessens the confusion, but I now have heartburn why the following are not all identical? The rule for a Constant assignment takes precedence over the datatype?

Code: Select all

Define.d x,y, divisor2, divisor3
Define.i ix,iy, idivisor2, idivisor3
divisor2 = 2
divisor3 = 3
idivisor2 = 2
idivisor3 = 3
Debug "-- Integers assigned a Double constant --"
ix = 1.0 / 2
iy = 1.0 / 3
If ix
  Debug "I:1.0/2  = True"
Else
  Debug "I:1.0/2  = False"
EndIf
If Bool(ix)
  Debug "BI:1.0/2 = True"
Else
  Debug "BI:1.0/2 = False"
EndIf
If iy
  Debug "I:1.0/3  = True"
Else
  Debug "I:1.0/3  = False"
EndIf
If Bool(iy)
  Debug "BI:1.0/3 = True"
Else
  Debug "BI:1.0/3 = False"
EndIf
Debug "-- Integers assigned a Double variable --"
ix = 1.0 / divisor2
iy = 1.0 / divisor3
If ix
  Debug "I:1.0/2  = True"
Else
  Debug "I:1.0/2  = False"
EndIf
If Bool(ix)
  Debug "BI:1.0/2 = True"
Else
  Debug "BI:1.0/2 = False"
EndIf
If iy
  Debug "I:1.0/3  = True"
Else
  Debug "I:1.0/3  = False"
EndIf
If Bool(iy)
  Debug "BI:1.0/3 = True"
Else
  Debug "BI:1.0/3 = False"
EndIf
Debug "-- Integers assigned a Double variable --"
ix = 1.0 / idivisor2
iy = 1.0 / idivisor3
If ix
  Debug "I:1.0/2  = True"
Else
  Debug "I:1.0/2  = False"
EndIf
If Bool(ix)
  Debug "BI:1.0/2 = True"
Else
  Debug "BI:1.0/2 = False"
EndIf
If iy
  Debug "I:1.0/3  = True"
Else
  Debug "I:1.0/3  = False"
EndIf
If Bool(iy)
  Debug "BI:1.0/3 = True"
Else
  Debug "BI:1.0/3 = False"
EndIf
; -- Integers assigned a Double constant --
; I:1.0/2  = True
; BI:1.0/2 = True
; I:1.0/3  = False
; BI:1.0/3 = False
; -- Integers assigned a Double variable --
; I:1.0/2  = False
; BI:1.0/2 = False
; I:1.0/3  = False
; BI:1.0/3 = False
; -- Integers assigned a Double variable --
; I:1.0/2  = False
; BI:1.0/2 = False
; I:1.0/3  = False
; BI:1.0/3 = False
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
User avatar
Josh
Addict
Addict
Posts: 1183
Joined: Sat Feb 13, 2010 3:45 pm

Re: If, Bool - rounded Floats

Post by Josh »

I am a user of Pb and I am not interested in compiler-internas. If and Bool belong to the basic things of a programming language and there Pb should bring a result which is to be expected.

Other confusing examples:

Code: Select all

q.q = 2
d.d = 2.1

;Example with variables
Debug Bool (q = d) ; 1
Debug Bool (d = q) ; 0

;Same example with literals
Debug Bool (2 = 2.1) ; 0.0 (since when is a boolean value a float)
Debug Bool (2.1 = 2) ; 0.0
sorry for my bad english
User avatar
skywalk
Addict
Addict
Posts: 3997
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: If, Bool - rounded Floats

Post by skywalk »

'0.0 +' saves the day :wink:

Code: Select all

; Example with variables
Debug Bool(0.0 + q = d) ; 1
Debug Bool(0.0 + d = q) ; 0
; Example with literals
Debug Bool(0.0 + 2 = 2.1) ; 0.0 (since when is a boolean value a float)
Debug Bool(0.0 + 2.1 = 2) ; 0.0
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
Post Reply