blitzpp / blitz

Blitz++ Multi-Dimensional Array Library for C++
https://github.com/blitzpp/blitz/wiki
Other
405 stars 84 forks source link

min([NaN,NaN]) != NaN #68

Closed slayoo closed 5 years ago

slayoo commented 5 years ago

Migrated from: https://sourceforge.net/p/blitz/bugs/35/

The following code:

#include <blitz/array.h>
using namespace blitz;
int main()
{
Array<float, 3> arr(Range(0,10));
arr = quiet_NaN(float(0));
std::cout << "min: " << min(arr) << std::endl;
std::cout << "max: " << max(arr) << std::endl;
}

... gives the following output:

$ ./a.out
min: 3.40282e+38
max: -3.40282e+38

... which is (arguably) kind of non-intuitive.

In particular, an assertion using isnan(min()) or finite(min()) would not detect presence of NaNs, which is yet more non-intuitive

Patrik's comment from the mailing list:

Yeah, that's suboptimal. NaN isn't greater or less than anything, so the initial value never gets replaced in the reduction. We can't just check if the result is huge, because the result COULD actually be huge. We'd need a separate comparison against NaN for all elements (but only for T_numtypes that actually have NaN.)

However, that would change the existing behavior which (I assume) says that min([ 1 2 3 NaN]) is 1 and not NaN. What's the desired behavior here. It seems reasonable to have the NaN always be captured in the reduction.

Initializing the min/max reductions with the first value as opposed to with huge/neghuge should take care of this. However, I'm having difficulties making that change without breaking stuff.

citibeth commented 5 years ago

This is not a bug, it is a "feature" of the IEEE 754 floating point standard.