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. |