# NAN: What is it good for? (programming)

I’m afraid it will reveal my oldish age, but the CDC 6600 from the early 1960’s had four special floating point values (+infty, -infty, +indet, -indet) and IIRC no trapping mechanism. The numbers were somewhat “well-behaved” in that adding +infty to anything except indet or -infty resulted in +infty, the other cases indet. 0/0 resulted in indet, other divisions by zero resulted in +infty or -infty.

(With little trouble I might recall more idiosyncracies of this machine I’ve not seen for 40-odd years, even though I can’t recall yesterday’s breakfast. :smack: )

Also known as, “Ice-NAN”.

In the specific case that prompted the question (yes, of course there was a specific case), the NANs that I was seeing ultimately came from INFs, and the INF (actually, -INF) came from a log(0). If the program had given an error of “Invalid argument for log” or something like that, then I could have gone through and checked all of the log calls in the program, and found the problem a lot more easily.

And the IEEE standard which introduced NAN might have been back in the 70s, but I certainly remember writing programs that crashed on division by zero as late as the 90s. Maybe the standard was just slow to be adopted, I don’t know.

Despite the floating point specification for hardware/assembly, whether or not you get ERRDIVs is implementation dependent. For instance, see the difference in Python and Lua from the terminal on my Mac:

\$python
>>> print(1/0)
ZeroDivisionError: integer division or modulo by zero
>>> print(0/0)
ZeroDivisionError: integer division or modulo by zero
– Note: these are ints, so NAN doesn’t apply, right? –
>>> print(0.0/0.0)
– Should return NAN from hardware, given specification –
ZeroDivisionError: float division by zero
>>> print(1.0/0.0)
ZeroDivisionError: float division by zero

\$lua -i
>= 1/0
inf
>= -1/0
-inf
>= 0/0
nan

I’ll spare you the terminal dump, but rest assured it works for +/-1.0 and 0.0 as well.

So even though the hardware specifies nan or inf be returned from the internal registers/ALU in case of nonreal or indeterminate return values, there’s still language dependency in whether or not the actual functions give you nan and inf, or if you get an error.

Are you programming in C on Unix, by chance? If so, you can set up your program so that floating point exceptions will generate signals, which you can catch yourself, or which will halt your program immediately (but this then is also catchable when running under a debugger).

Some sample code for this is here.

No such luck-- It’s FORTRAN 77.

Is there any particular reason why you need to program in FORTRAN 77? There are a number of languages which would allow you the kind of control over how to respond to arithmetic exceptions that you desire and to which acclimating yourself would likely not be very difficult.

(It may also be possible to obtain such control in FORTRAN 77; it’s just that you probably know more about the details of FORTRAN 77 than any of us do. At any rate, according to Wikipedia, floating point exception handling is at least a feature of later versions of FORTRAN)

Man oh man, you’re still on that gig?

But I would rather light a candle, than curse your darkness. Maybe one of these will help.
[ul]
[li]How to handle floating-point exceptions in Fortran[/li][li]Fortran Programming Guide (Solaris), Chapter 6, Floating-Point Arithmetic[/li][li]Compiler and tools tricks, floating-point (for g77 and gfortran).[/li][/ul]
It looks like there’s no standardized way to handle these in Fortran. Every combination of platform and compiler needs something different.

I use it in a C# .NET app I’m working on to represent unknown values. It’s a type of hardware monitoring application, and sometimes we get messages from the hw that indicate ‘unknown’ for particular values.

Until I finish my thesis. It’s that, or re-write about 500 pages of code.

But I’ll take a look at those links, anyway. I’ve gotten past this particular problem (all my numbers are now numbers), but there might be other things in there I can use.