发布于 2015-06-18 20:22:27
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
的1:1替代品。函数std::min
和std::max
是不可交换的。要获得与fmin
和fmax
的doubles相同的结果,应该交换参数
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则从一个数学库中调用它们。用于带有-O3
的fmax
的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和克朗来说,使用-Ofast
fmax
变得很简单
maxsd xmm0, xmm1
因此,这再次表明std::max
是fmax
的子集,并且当您使用没有nan
或带符号0的松散浮点模型时,fmax
和std::max
是相同的。显然,同样的论点也适用于fmin
和std::min
。
https://stackoverflow.com/questions/1632145
复制相似问题