std::min、std::max 和 fmin 和 fmax 之间有一个重要区别。
std::min(-0.0,0.0) = -0.0
std::max(-0.0,0.0) = -0.0
而
fmin(-0.0, 0.0) = -0.0
fmax(-0.0, 0.0) = 0.0
所以std::min 不是fmin 的一对一替代品。函数std::min 和std::max 不可交换。要获得与 fmin 和 fmax 的双打相同的结果,应该交换参数
fmin(-0.0, 0.0) = std::min(-0.0, 0.0)
fmax(-0.0, 0.0) = std::max( 0.0, -0.0)
但据我所知all these functions are implementation defined anyway in this case,所以要 100% 确定您必须测试它们是如何实现的。
还有一个重要的区别。对于x ! = NaN:
std::max(Nan,x) = NaN
std::max(x,NaN) = x
std::min(Nan,x) = NaN
std::min(x,NaN) = x
而
fmax(Nan,x) = x
fmax(x,NaN) = x
fmin(Nan,x) = x
fmin(x,NaN) = x
fmax可以用下面的代码模拟
double myfmax(double x, double y)
{
// z > nan for z != nan is required by C the standard
int xnan = isnan(x), ynan = isnan(y);
if(xnan || ynan) {
if(xnan && !ynan) return y;
if(!xnan && ynan) return x;
return x;
}
// +0 > -0 is preferred by C the standard
if(x==0 && y==0) {
int xs = signbit(x), ys = signbit(y);
if(xs && !ys) return y;
if(!xs && ys) return x;
return x;
}
return std::max(x,y);
}
这表明std::max 是fmax 的子集。
查看程序集显示 Clang 使用 fmax 和 fmin 的内置代码,而 GCC 从数学库中调用它们。 fmax 和 -O3 的 clang 程序集是
movapd xmm2, xmm0
cmpunordsd xmm2, xmm2
movapd xmm3, xmm2
andpd xmm3, xmm1
maxsd xmm1, xmm0
andnpd xmm2, xmm1
orpd xmm2, xmm3
movapd xmm0, xmm2
而对于std::max(double, double) 它只是
maxsd xmm0, xmm1
但是,对于 GCC 和 Clang,使用 -Ofast fmax 变得简单
maxsd xmm0, xmm1
因此这再次表明std::max 是fmax 的子集,并且当您使用没有nan 或符号零的更宽松的浮点模型时,fmax 和std::max 是相同的.同样的论点显然适用于fmin 和std::min。