[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi] Shouldn't std::max() and std::min() be commutative?
From: |
Greg Chicares |
Subject: |
[lmi] Shouldn't std::max() and std::min() be commutative? |
Date: |
Sat, 27 Feb 2021 13:13:47 +0000 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.4.0 |
Surely it is possible to implement std::max() and std::min() as
commutative operations [below], so I wondered whether it is not
therefore at least a QoI issue that libstdc++
$g++ --version
g++ (Debian 10.2.1-6) 10.2.1 20210110
does not. The answer is that libstdc++ follows the standard, e.g.,
C++20 (n4861) [alg.min.max / 3]:
"Remarks: Returns the first argument when the arguments are equivalent."
Is it not therefore a defect of the standard that it prescribes the
jarring and unnecessary behavior demonstrated below? What might they
have been thinking--that a commutative implementation such as this
quick sketch for type double:
#include <cmath>
constexpr bool operator()(T const& lhs, T const& rhs) const
{
if(0.0 == lhs && 0.0 == rhs)
{
return std::signbit(rhs) < std::signbit(lhs);
}
else
{
return lhs < rhs;
}
}
would be too slow?
Or is there some deeper reason--e.g., that using a weak order
everywhere in the standard is more important than commutativity here?
Demonstration:
#include <algorithm>
#include <cfloat>
int main()
{
std::cout << std::max( 0.0, -0.0) << std::endl; // prints 0
std::cout << std::min( 0.0, -0.0) << std::endl; // prints 0
std::cout << std::max(-0.0, 0.0) << std::endl; // prints -0
std::cout << std::min(-0.0, 0.0) << std::endl; // prints -0
double n = DBL_TRUE_MIN;
double a = 0.1 * n;
double b = -0.1 * n;
std::cout << a << std::endl; // prints 0
std::cout << b << std::endl; // prints -0
std::cout << std::max(a, b) << std::endl; // prints 0
std::cout << std::min(a, b) << std::endl; // prints 0
std::cout << std::max(b, a) << std::endl; // prints -0
std::cout << std::min(b, a) << std::endl; // prints -0
return 0;
}
- [lmi] Shouldn't std::max() and std::min() be commutative?,
Greg Chicares <=