detecting NaN

BlitzMax Forums/BlitzMax Programming/detecting NaN

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!

This should do the trick:

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

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!"


WTF.

Funny thing I was just in need for this.
Thanks.

I've had succes in the past with :

If n = n + 1 then 


thats cool
if n=n+1 then
catches both cases

neat solution

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


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.

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.

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"

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

it is then!

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.

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.

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?

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.