Page 1 of 1

How Can I Test For #INF

Posted: Sat Aug 27, 2005 11:20 pm
by Dreglor
In a Float Number How do I Test For #INF
like if the program did a division by zero I want to test that?

Posted: Sun Aug 28, 2005 10:59 pm
by netmaestro
My guess would be the onerrorgosub() command and handle the error based on its error number.

Posted: Mon Aug 29, 2005 12:35 am
by Fou-Lu
PB could return this constant, just like Blitz (I think) does. Is that possible? Fred?

netmaestro sugestion is good, but if you want to store that value in a variable #INF would be necessary.

Posted: Mon Aug 29, 2005 1:20 am
by jack

Code: Select all

OpenConsole()

x.f=1.0
y.f=0.0
z.f=x/y

Procedure IsInforNaN(x.f) 
  ! mov ebx,dword [esp]
  ! xor eax, eax
  ! xor  ecx, ecx
  ! cmp  ebx, $ff800000 ;-Inf
  ! sete  cl
  ! xor  edx, edx
  ! cmp  ebx, $7f800000 ;+Inf
  ! sete  dl
  ! or  ecx, edx
  ! xor  edx, edx
  ! cmp  ebx, $ffc00000 ; Ind
  ! sete  dl
  ! or  ecx, edx
  ! xor  edx, edx
  ! cmp  ebx, $7fc00000 ; NaN
  ! sete  dl
  ! or  ecx, edx
  ! je  @
  ! mov  eax, 1
  !@:  
  ProcedureReturn
EndProcedure 

PrintN(Str(IsInforNaN(z)))
PrintN("press return key to end")
Input()
CloseConsole()

Posted: Tue Aug 30, 2005 12:36 am
by Dreglor
thanks :D

Posted: Wed Aug 31, 2005 1:45 pm
by Dare2
Thanks Jack,

That just saved me a good deal of time! :)

Posted: Wed Aug 31, 2005 2:07 pm
by jack
you'r welcome :)

Posted: Wed Aug 31, 2005 3:39 pm
by Rescator
Hmm! Shame there is no possibility to do:

If z=#INF00 or z=#IND00

and similar.

If you use PeekL(@z) you will see hex values like

$7F800000 (same as 1.#INF00)
$FFC00000 (same as 1.#IND00)

I don't know what the other float return codes are.

Interesting example:

Code: Select all

x.f=1.0
y.f=0.0
z.f=x/y
a.f=b/c
Debug StrF(z)
Debug StrF(a)

If PeekL(@z)=$7F800000 ;same as 1.#INF00
 Debug "Is #INF"
ElseIf PeekL(@z)=$FFC00000 ;same as 1.#IND00
 Debug "Is #IND"
Else
 Debug "No errors!"
EndIf

If PeekL(@a)=$7F800000 ;same as 1.#INF00
 Debug "Is #INF"
ElseIf PeekL(@a)=$FFC00000 ;same as 1.#IND00
 Debug "Is #IND"
Else
 Debug "No errors!"
EndIf


Posted: Wed Aug 31, 2005 4:39 pm
by jack
Actually the code I posted is equivalent to

Code: Select all

If (x=-Infinity) Or (x=+Infinity) Or (x=Indeterminate) Or (x=NaN)
  ProcedureReturn 1
Else
  ProcedureReturn 0
EndIf

Posted: Thu Sep 01, 2005 6:04 am
by Rescator
Hmm! Modify it maybe to return a returnval indicating what the condition was?

Being able to know not only if a special float case occured,
but also able to check what type it was is vital some times right?

So what if all ok is 0 and +INF is 1 and -INF is 2 and IND is 3 does that make sense?
Or can the +INF and -INF just be the same (just INF) and check the float variable sign what it was?

Posted: Thu Sep 01, 2005 7:17 am
by Rescator
I modified your code a bit, now it returns return codes indicating type of error.
And (you asm experts please verify this) I seem to have simplified the code a bit too.
Or is there a way to make this code even tighter/faster?

Code: Select all

x.f=-1.0
y.f=0.0
z.f=x/y

Procedure IsInforNaN(x.f)
 ! mov ebx,dword [esp]

 ! cmp  ebx, $ff800000 ;If -Inf then 1 will be returned
 ! mov  eax, 1
 ! je  @

 ! cmp  ebx, $7f800000 ;If +Inf then 2 will be returned
 ! mov  eax, 2
 ! je  @

 ! cmp  ebx, $ffc00000 ; If Ind then 3 will be returned
 ! mov  eax, 3
 ! je  @

 ! cmp  ebx, $7fc00000 ; If QNaN then 4 will be returned
 ! mov  eax, 4
 ! je  @

 ! mov  eax, 0 ;If float seems ok, return 0

 !@: 
 ProcedureReturn
EndProcedure

Debug IsInforNaN(z)
Debug z

Posted: Thu Sep 01, 2005 8:24 am
by Dreglor
even better ;)

thanks again

Posted: Thu Sep 01, 2005 2:03 pm
by jack
very good Rescator :)