# The implementation of Min and Max operations for floating-point types

Story about differences in software implementations of simple mathematical operations answering the question: “Which of two floating-point values are greater” (or lower).

The float-related implementations of Min and Max are different and in most cases their behavior is not conforming to
IEEE-754–2008 standard (IEEE Standard for Binary Floating-Point Arithmetic).

Consider the following example of naïve generic Max JavaScript implementation:

`function Max(a, b) {  if(a > b) {    return a;   } else {    return b;   }}`

This implementation isn’t correct in many ways:

• It cannot handle -0 +0 cases (+0 should be greater than -0);
• It doesn’t handles input and number of arguments according to JavaScript specification (-Infinity / +Infinity cases)

And most interesting:

• It cannot handle NaN value correctly (Not-a-Number)

But what is the correct way of handling NaN situation, when a is NaN or b is NaN, or both a and b is NaN. As soon as wee use floating-point numbers we can find citations of IEEE standard and then we will find definitions of minNum and maxNum operations,
which prefer numbers over NaN values, so Max(NaN, number) = Max(number, NaN) = number.

But there are not so many modern IEEE-compatible implementations.

#### IEEE 754–2008 compatible NaN handling libraries,

where Max(NaN, number) = Max(number, NaN) = number:
C language, since C99 http://en.cppreference.com/w/c/numeric/math/fmax

#### IEEE 754–2008 incompatible NaN handling libraries,

where Max(NaN, number) = Max(number, NaN) = NaN:

#### Examples of libraries throwing exceptions in case of NaN arguments:

• Ruby (there are max/min methods defined on Enumerable, no standard Max/Min implementations),
will throw “comparison of Float with NaN failed”. But NaN class is still float. Older version of ruby interpreter can throw “comparison of Float with Float failed” exception.

#### Non-commutative behavior

where Max(number, NaN) isn’t equal to Max(NaN, number)

Workarounds available.

#### Conclusion

It seems that most of the time we should ensure that all of arguments of Min/Max functions are not NaNs, because results can be spoiled by other argument depending on Min/Max implementation.
IEEE standard defines standard behavior, but most of the time in modern languages you will see another behavior.
Why?

• It seems that is because there are no other way of getting error source in result, except exception. And exceptions are considered slow;
• Engineers are making standard libraries by looking at other standard libraries implementations;