# 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:*

- ECMAScript,

specification http://www.ecma-international.org/ecma-262/5.1/#sec-15.8.2.11 and V8 implementation https://github.com/v8/v8/blob/cd81dd6d740ff82a1abbc68615e8769bd467f91e/src/js/math.js#L77 - .NET (C#, F# and others using Math module, max operator for F#)

https://github.com/dotnet/coreclr/blob/bc146608854d1db9cdbcc0b08029a87754e12b49/src/mscorlib/src/System/Math.cs#L381

#### 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)*

Swift, Haskell, OCaml

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;
- Standard pdf itself isn’t available for free.
- Generic one-for-all implementation looks attractive.
- This is a corner case which is not important most of the time for developers. We should just sit and wait until the problem strikes.

p.s. There is also (± Infinity, NaN) corner case.

Although Standard entries about float operations are available, it’s better for you to read [your_favorite_programming_language] language specification first.