In this (very interesting) talk the speaker poses a question:
What is the e value for the float/std::min monoid.
In other words: what is the identity element for the monoid composed of standard C++ floats and std::min operation? The speaker says that the answer is "interesting".
I think that std::numeric_limits<float>::infinity() should be the answer, as evidenced by the code:
const auto max = numeric_limits<float>::max();
const auto min = numeric_limits<float>::min();
const auto nan = numeric_limits<float>::signaling_NaN();
const auto nan2 = numeric_limits<float>::quiet_NaN();
const auto inf = numeric_limits<float>::infinity();
const auto minus_inf = -inf;
cout << std::min(max, inf) << "\n";
cout << std::min(min, inf) << "\n";
cout << std::min(nan, inf) << "\n";
cout << std::min(nan2, inf) << "\n";
cout << std::min(inf, inf) << "\n";
cout << std::min(minus_inf, inf) << "\n";
Which prints:
3.40282e+38
1.17549e-38
nan
nan
inf
-inf
We always get the left argument when calling std::min in the tests. Is infinity the correct answer or am I missing something?
EDIT: I seemed to have missed something. This:
cout << std::min(nan, inf) << "\n";
cout << std::min(inf, nan) << "\n";
prints:
nan
inf
So we get different answers based on the order of arguments in case of NaN shenanigans.
It's obviously true that
minon the affinely-extended reals (ie, including +/-inf but excluding NaN) is a monoid.However, the result of comparing anything to
NaNis not false, but "unordered". This implies that<is only a partial order onfloat, andstd::min<float>(which is defined in terms of<) is therefore not a monoid.There is in IEEE 754 a
totalOrderpredicate - although I don't know how it is exposed in C++, if at all. We could write our ownminin terms of this instead of<, and that would form a monoid ... but it wouldn't bestd::min.For confirmation, we can compile a variant of your code on godbolt, to see how this is implemented in practice:
the comparison is done with
comiss, which has the possible resultsand specifies that
the branch is done with
jbe, which willYou can see that the UNORDERED result is actually treated as both less than and equal by this conditional branch.
So, assuming this is a legal model of the unordered comparison mentioned by IEEE 754, it should be permissible to have both
and
which means
min<float>is not associative and is therefore not a monoid.