detecting NaN

BlitzMax Forums/BlitzMax Programming/detecting NaN

Chris C(Posted 2006) [#1]
Local n:Double=100000
n:*n;n:*n;n:*n;n:*n;n:*n;n:*n;n:*n;n:*n;n:*n;n:*n;n:*n;n:*n;n:*n
'1.#INF000000000000
Print n
n=Sqr(-1)
'-1.#IND000000000000
Print n


how would I check for these two states?
if NAN then ...

would be nice!


Michael Reitzenstein(Posted 2006) [#2]
This should do the trick:

Const Inf! = 9999.0^9999.0
Const Nan! = (-1.0)^(0.5)


Chris C(Posted 2006) [#3]
well done!

interestingly
-1.#IND000000000000 is equal to Inf! And Nan!

Const Inf! = 9999.0^9999.0
Const Nan! = (-1.0)^(0.5) 

Local n:Double=100000
n:*n;n:*n;n:*n;n:*n;n:*n;n:*n;n:*n;n:*n;n:*n;n:*n;n:*n;n:*n;n:*n
'1.#INF000000000000
Print n
If n=Inf Then Print "inf!"
If n=nan Then Print "nan!"


n=Sqr(-1)
'-1.#IND000000000000

Print n
If n=nan Then Print "nan!"
If n=Inf Then Print "inf!"



Amon(Posted 2006) [#4]
WTF.


Haramanai(Posted 2006) [#5]
Funny thing I was just in need for this.
Thanks.


Difference(Posted 2006) [#6]
I've had succes in the past with :

If n = n + 1 then 



Chris C(Posted 2006) [#7]
thats cool
if n=n+1 then
catches both cases

neat solution


Michael Reitzenstein(Posted 2006) [#8]
No, that returns false positives for very large, but not infinite, doubles:

Local blah! = 100 * 10^100
Print blah

If ( blah = blah + 1 )

	Print "yes"
	
EndIf



Difference(Posted 2006) [#9]
I don't think that's a false positive. It's maybe even a case that Blitz should catch? Look at this:

Local blah! = -100 * 10^100
Print blah

If ( blah = blah + 100000000 )

	Print "yes"
	
EndIf


blah! is trashed, - you can't change it's value anymore.


Michael Reitzenstein(Posted 2006) [#10]
The code is meant to check for NaN/Inf, and it's saying that very large numbers are, when they're not.

As for not being able to change the value of the number, that's how floats work. 100 million might seem like a large number, but the range of a double is +/- 10^308. You can change its value, but 100 million is too small to make a difference.


Difference(Posted 2006) [#11]
True, it's just that I can't seem to bring blah! "back to life" (into a normal working range again). It seems no matter what I add it ends up being "-9.9999999999999998e+101"


Chris C(Posted 2006) [#12]
Const Inf! = 9999.0^9999.0
Const Nan! = (-1.0)^(0.5)

it is then!


Floyd(Posted 2006) [#13]
I would go straight to the definitions of infinity and NaN for this.

A double is 64 bits: 1 bit sign, 11 bit exponent, 52 bit mantissa.

Infinity and NaN are distinguished by the exponent being as large as possible, i.e. all 1-bits.

' Check if number is finite.


Local u:Double = 2   ' also works for floats

For Local n = 1 To 12
	Print isfinite(u) + "  " + u
	u :* u
Next

Print
Print "What about NaN?"
Print

u = u - u
Print isfinite(u) + "  " + u


Function isfinite( x:Double )    ' assumes Intel byte order

	Const EXP_BITS = %01111111111100000000000000000000
	
	Local bits = ( Int Ptr Varptr x )[1]  ' [0] for Mac? 
	
	Return ( bits & EXP_BITS ) <> EXP_BITS   ' exponent is all 1s for infinity or NaN
	
End Function

Note this is Intel only. Anybody want to make it multiplatform?
It shouldn't be difficult, but I don't have a Mac.


Chris C(Posted 2006) [#14]
all this and no ones made any grandmother or bread related jokes...

@floyd Shame I dont have a Mac either, wonder if some nice Mac user will come to our rescue.


deps(Posted 2006) [#15]
Output on a Mac using Local bits = ( Int Ptr Varptr x )[1] ' [0] for Mac?

1 2.0000000000000000
1 4.0000000000000000
1 16.000000000000000
1 256.00000000000000
1 65536.000000000000
1 4294967296.0000000
1 1.8446744073709552e+19
1 3.4028236692093846e+38
1 1.1579208923731620e+77
1 1.3407807929942597e+154
1 inf
1 inf

What about NaN?

1 nan


and with Local bits = ( Int Ptr Varptr x )[0] ' [0] for Mac?

1 2.0000000000000000
1 4.0000000000000000
1 16.000000000000000
1 256.00000000000000
1 65536.000000000000
1 4294967296.0000000
1 1.8446744073709552e+19
1 3.4028236692093846e+38
1 1.1579208923731620e+77
1 1.3407807929942597e+154
0 inf
0 inf

What about NaN?

0 nan



The second one looks best, but shouldn't it return 1 if the number is inf or nan?


Floyd(Posted 2006) [#16]
Thanks for testing this.

The second one, with [0], is correct.

The function isfinite(x) returns True, i.e. 1, for finite numbers and False for Infinity and NaN.