check for NaN?

Monkey Forums/Monkey Programming/check for NaN?

Anatol(Posted 2012) [#1]
Hi,

is it possible to check if a Float/Int is NaN?

A bit of background: I have a particle system that works with vectors (velocity, position) using the vector class at http://monkeycoder.co.nz/Community/post.php?topic=568&post=4319 . Individual particles are influenced by a number of vector forces (gravity, air resistance and touch swipes). It works all well, but when I swipe really quickly the velocity and position vectors of some particles become NaN, even particles that are outside the swipe force influence. As a result the particles disappear without any error message. This happens on all tested targets. I have no idea why as I only add or multiply vectors, but somewhere must be a Maths problem such as division by zero or Sqrt(-1).

So: I'm hoping that checking values for NaN would help me to troubleshoot. The whole code is too complex to post.

Any hint would be greatly appreciated.

Cheers!
Anatol


marksibly(Posted 2012) [#2]
Hi,

You can check for Nan by comparing a number with itself, eg:

Local t:=Sqrt(-1)
If t<>t Print "NaN!"

Note that division by zero isn't necessarily a Nan. See here for how Nans can be generated:

http://en.wikipedia.org/wiki/NaN


Anatol(Posted 2012) [#3]
Hi Mark,

thanks for your reply and also a million thanks for Monkey! I truly enjoy working with it!

Checking values for NaN helped me to locate the issue which was

±Infinity / ±Infinity

which as mentioned in the article you pointed out is NaN.

I can fix the issue by simply ignoring/skipping any vector force with NaN. It may not be 100% accurate but visually you can't tell.

The NaN is generated in the Vector class http://monkeycoder.co.nz/Community/post.php?topic=568&post=4319 , in the Normalize() method in X / Length and/or Y / Length.



Maybe it needs a precaution that checks if both Length And (X Or Y) are ±Infinity.

Is there any way in Monkey to check for Infinity?

I'm still uncertain where the problematic values (Infinity) come from, though. In my project this only seems to happen with fast movements and only when a larger number of particles get affected by a vector force. Even though I figured out a workable solution I would love to find the actual issue.


marksibly(Posted 2012) [#4]
Hi,

> Is there any way in Monkey to check for Infinity?

Infinity is constant, so a compare should work.

I think I'll add some stuff to the math module to help with these issues, how about...?

Const POSITIVE_INFINITY#=...not sure how I'll do this yet!...
Const NEGATIVE_INFINITY#=

Function IsNan?( n# )   'really needed?
   Return n<>n 
End

Function IsFinite?( n# )   'check for valid values - JS has it I think, seems useful...
   Return n=n And n<>POSITIVE_INFINITY And n<>NEGATIVE_INFINITY
End


As for your code, I dunno. Yes, it'll prevent NaNs, but it also silently changes your program's logic! Probably better to work out what's going wrong in the first place.

Can you post some code?


Floyd(Posted 2012) [#5]
Checking values for NaN helped me to locate the issue which was ±Infinity / ±Infinity

If that is coming from the Normalize method then X or Y must already be infinite and the debugging task is to find out how that happened. It is usually the result of dividing by zero.

Look for a place where X or Y is set to something/zero.


Anatol(Posted 2012) [#6]
Hi,

thanks for your replies. I would appreciate some additions to the math module.

>Infinity is constant, so a compare should work.

I'm not sure if you mean that, but I'm now just checking against a "really high number" e.g.
value > 99999999999999999999
That's probably not the best way though.

Anyway, it helped and I figured out the problem - sort of. As mentioned earlier I use a particle system that works with vectors. I add vector forces to the particles' velocity using the vector class http://monkeycoder.co.nz/Community/post.php?topic=568&post=4319

When I set the drag force vector using

dragForce.Length = someLength
dragForce.Direction = someAngle


I sometimes get to the Infinity result if the length is a large number which consequently creates a NaN, and once the velocity length (speed) is set to NaN the entire particle disappears indefinitely.

This doesn't happen if I set the length and direction using MakeField() which calculates the vector in a different way.

dragForce.MakeField(someAngle, someLength)


Still the occasional high velocity speed, but it doesn't result in a NaN.

Thanks again.