From: Clive Page on
In the physical sciences you often need a way of representing null
values, e.g. values from measurements you haven't been able to take yet.
Databases supporting SQL support nulls pretty well, but it's harder in
compiled languages. In many cases in compiled languages like Fortran it
works pretty well if you use IEEE NaN values to represent nulls in real
data types. These, especially quiet NaNs, pretty much propagate
through arithmetic expressions and assignments in the way you would
expect.

But I've just been surprised by the fact that functions like MIN and MAX
aren't predictable when one of their arguments is a NaN (and the others
are not). Results so far on 3 compilers that I have handy:

g95: returns NaN

gfortran: ignores NaNs, returns min/max of the other args

NAG f95: returns NaN

I can't find anything in the IEEE floating-point standard nor in Fortran
2003 that is relevant. It's a pity that MIN and MAX are
system-dependent in this way. I would really like them to ignore NaNs
in the way that SQL's aggregate functions ignore nulls, but at present
(on a sampling of just three) the majority of compilers do the opposite.

It's not even clear to me which Standard would need to be updated to
bring about the desirable uniformity.



--
Clive Page
From: glen herrmannsfeldt on
Clive Page wrote:

> In the physical sciences you often need a way of representing null
> values, e.g. values from measurements you haven't been able to take yet.
> Databases supporting SQL support nulls pretty well, but it's harder in
> compiled languages. In many cases in compiled languages like Fortran it
> works pretty well if you use IEEE NaN values to represent nulls in real
> data types. These, especially quiet NaNs, pretty much propagate
> through arithmetic expressions and assignments in the way you would expect.

I believe R does that, and it does work pretty well. But I thought R
had both NA and NaN.

> But I've just been surprised by the fact that functions like MIN and MAX
> aren't predictable when one of their arguments is a NaN (and the others
> are not). Results so far on 3 compilers that I have handy:

> g95: returns NaN

> gfortran: ignores NaNs, returns min/max of the other args

> NAG f95: returns NaN

> I can't find anything in the IEEE floating-point standard nor
> in Fortran 2003 that is relevant.

For the usual definition of IEEE NaN, returning NaN is probably
the right thing to do. It might be that new functions that ignore
NaN should be defined. Since there is already MAX0 and MAX1,
how about MAX2? (I like it better than MAXNA.)

-- glen

From: FX on
There has been a bit of discussion about that issue in the past, in a
thread named "Fortran / IEEE 754: MAXVAL and INF, NaN". The issues and
differences between MAX and MAXVAL are tricky, and I haven't seen any
answer that quite convinced me that there is a consensus or a definite
standard answer.

Just to stress the large number of possible interpretations of the
standard, here is what a few compilers output for MINVAL((/nan,nan/)) and
MAXVAL((/nan,nan/)) where nan is a variable that contains... I'm sure you
guessed :)

Intel: Inf, -Inf
Sun: -NaN, -NaN (yes, that's a negative NaN; don't ask)
g95: Huge, -Huge
gfortran: Huge, -Huge
portland: NaN, -Huge
MIPSpro: Inf, NaN
IBM: Huge, -Huge

(where Inf is an infinity and Huge is huge(nan)).

--
FX
From: Paul van Delst on
FX wrote:
> There has been a bit of discussion about that issue in the past, in a
> thread named "Fortran / IEEE 754: MAXVAL and INF, NaN". The issues and
> differences between MAX and MAXVAL are tricky, and I haven't seen any
> answer that quite convinced me that there is a consensus or a definite
> standard answer.
>
> Just to stress the large number of possible interpretations of the
> standard, here is what a few compilers output for MINVAL((/nan,nan/)) and
> MAXVAL((/nan,nan/)) where nan is a variable that contains... I'm sure you
> guessed :)
>
> Intel: Inf, -Inf
> Sun: -NaN, -NaN (yes, that's a negative NaN; don't ask)
> g95: Huge, -Huge
> gfortran: Huge, -Huge
> portland: NaN, -Huge
> MIPSpro: Inf, NaN
> IBM: Huge, -Huge
>
> (where Inf is an infinity and Huge is huge(nan)).

In IDL, there is the FINITE() command to pick out nan's and inf's.

I Probably should know the answer to this, but is there something similar in Fortran such
that if you had the following,

x = (/1.0,3.4,5.6,nan,724.74,3.87,inf,54.36/)

you could do something like,

WHERE(finite(x)) xmax = maxval(x)

??


cheers,

paulv
From: glen herrmannsfeldt on
Clive Page wrote:
(snip)

> I can't find anything in the IEEE floating-point standard nor in Fortran
> 2003 that is relevant. It's a pity that MIN and MAX are
> system-dependent in this way.

Fortran 2003, section 13.7:

"A program is prohibited from invoking an intrinsic procedure
under circumstances where a value to be returned in a subroutine
argument or function result is outside the range of values
representable by objects of the specified type and type parameters,
unless the intrinsic module IEEE ARITHMETIC (section 14) is
accessible and there is support for an infinite or a NaN result,
as appropriate. If an infinite result is returned, the flag IEEE
OVERFLOW or IEEE DIVIDE BY ZERO shall signal; if a NaN result is
returned, the flag IEEE INVALID shall signal. If all results are
normal, these flags shall have the same status as when the
intrinsic procedure was invoked."

Fortran 2003, section 14.8:

"The inquiry function IEEE SUPPORT NAN is provided to inquire
whether the processor supports IEEE NaNs. Where these are
supported, their behavior for unary and binary operations,
including those defined by intrinsic functions and by
functions in intrinsic modules, shall be consistent with
the specifications in the IEEE International Standard."

Note that MIN and MAX with more than two arguments are not
unary or binary operations, and so not applicable to this
statement.

-- glen