# GameMaker: Working with NaN and infinities This is a kind of a blog post that you probably don't need unless you've already had an encounter with its subject.

## What are these

GameMaker uses IEEE 754 double-precision (64-bit) floating-point arithmetic for operations with non-integer values, which means that you will occasionally deal with infinities and NaN.

Infinities are pretty straightforward - you may get one by dividing a positive or a negative value by zero, or simply producing a value that's too big to hold for the type (for user-defined variables, calculating 100160 through multiplication will do).
Trying to add/subtract values from an infinity will still give you an infinity, but you can change the sign of it.

NaN is trickier - you will most often see it when dividing a zero by zero, but it is also seen in other "undefined" situations like dividing an infinity by an infinity, or multiplying an infinity by zero.

As result, and particularly when dealing with user input, you may occasionally have to deal with the two.

GameMaker versions released in mid-2019 and later have built-in `NaN` and `infinity` constants and `is_nan`/`is_infinity` functions for checking.

Therefore you can do

```var f = 1/0; // or `f = infinity`
show_debug_message(f); // "inf"
show_debug_message(is_infinity(f)); // true

var n = 0/0; // or `f = NaN`
show_debug_message(n); // "NaN"
show_debug_message(is_nan(n)); // true
```

## Older GMS2 versions

Older GMS2 versions handled NaN and infinity largely correctly, but didn't offer helper constants/functions.

Obtaining the values is still trivial, but there's a catch - GameMaker's compiler tries to collapse operations on constant expressions, and wasn't happy with the idea of dividing by zero up to GMS2.3 or so.

Therefore you'll need an intermediate variable to store a zero in.

You could have a script to initialize one and define macros, supposed named `nonfin_init`:

```/// nonfin_init()
gml_pragma("global", "global.__zero = 0");
#macro NaN (0 / global.__zero)
#macro infinity (1 / global.__zero)
```

`gml_pragma` would cause the variable to be initialized on game start, but you could also run it yourself if you rely on execution order.

Implementing `is_nan` is mostly straightforward: NaN is infamous for not being equal to itself.

```/// is_nan(number)
/// @param number
return !(argument0 == argument0);
```

This could have been just a `!=`, but, for reasons most likely related to epsilon, old GMS2 versions also consider NaN to not be not equal to itself.

Checking that a value is an infinity is interesting - we have more than a few options.

I think that checking for `(1/inf)==0` is pretty reliable.

```/// is_infinity(number)
/// @param number
return sign(1 / argument0) == 0;
```

(GM's logic for `sign` is (f >= 0 ? (f == 0 ? 0 : 1) : -1), so sign of NaN is -1).

## GMS1

GMS1 is mostly the same, but, for reasons once again likely related to epsilon, considers infinity to not be equal to itself. Therefore the checks get a little strange - we also have to check for a sign (infinities are positive or negative, NaN is neither):

```/// is_nan(number)
var f = argument0;
return !(f == f) && !(f > 0) && !(f < 0);
```
```/// is_infinity(number)
var f = argument0;
return !(f == f) && ((f > 0) || (f < 0));
```

"constant" definitions remain the same, but you have to add them via menu:Resources➜Define Macros.

## GM8.1 and earlier

As far as I can tell, pre-2012 versions of GameMaker did not really support NaN/inf - division by zero is always throws a runtime error, and an "overflown" number prints as "ERROR" rather than any representation of infinity.

Perhaps passing numbers to a DLL would allow to properly inspect it?

That is all!

## 2 thoughts on “GameMaker: Working with NaN and infinities”

1. Felipe Vega on said:

Thank you for the GMS1 functions. Is there a way to create infinity and NaN in GMS1? This version cannot use macro afaik. Thanks!

• Vadim on said:

It can, but instead of a line of code it’s a little editor that you open using menu:Resources ➜ Define Macros

This site uses Akismet to reduce spam. Learn how your comment data is processed.