Hay una diferencia importante entre std::min
, std::max
y fmin
y fmax
.
std::min(-0.0,0.0) = -0.0
std::max(-0.0,0.0) = -0.0
mientras que
fmin(-0.0, 0.0) = -0.0
fmax(-0.0, 0.0) = 0.0
Así std::min
no es un sustituto para el 1-1 fmin
. Las funciones std::min
y std::max
no son conmutativas. Para obtener el mismo resultado con dobles junto fmin
y fmax
uno debe cambiar los argumentos
fmin(-0.0, 0.0) = std::min(-0.0, 0.0)
fmax(-0.0, 0.0) = std::max(0.0, -0.0)
Pero por lo que yo puedo decir all these functions are implementation defined anyway in this case Así que para estar 100% seguro de lo que tiene que probar cómo se implementan.
Hay otra diferencia importante. Para x ! = NaN
:
std::max(Nan,x) = NaN
std::max(x,NaN) = x
std::min(Nan,x) = NaN
std::min(x,NaN) = x
mientras que
fmax(Nan,x) = x
fmax(x,NaN) = x
fmin(Nan,x) = x
fmin(x,NaN) = x
fmax
puede ser emulado por el código siguiente
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);
}
Esto muestra que std::max
es un subconjunto de fmax
.
Al mirar el conjunto, se muestra que Clang usa el código incorporado para fmax
y fmin
, mientras que GCC los llama desde una biblioteca matemática.El montaje de sonido metálico de fmax
con -O3
es
movapd xmm2, xmm0
cmpunordsd xmm2, xmm2
movapd xmm3, xmm2
andpd xmm3, xmm1
maxsd xmm1, xmm0
andnpd xmm2, xmm1
orpd xmm2, xmm3
movapd xmm0, xmm2
mientras que para std::max(double, double)
es simplemente
maxsd xmm0, xmm1
Sin embargo, para GCC y Sonido metálico utilizando -Ofast
fmax
se convierte simplemente en
maxsd xmm0, xmm1
Así lo muestra esta Una vez más, std::max
es un subconjunto de fmax
y que cuando utiliza un modelo de punto flotante más flexible que no tiene nan
o cero firmado, entonces fmax
y std::max
son lo mismo. El mismo argumento obviamente se aplica a fmin
y std::min
.
Advertencia: min y max solo pueden comparar dos variables del mismo tipo ... por lo que no puede comparar un int y un doble con ellos :( –
True - max (1, 2.0) no funciona, tiene ser algo así como max (1, 2.0) o max (double (1), 2.0). –
Que es una buena cosa IMO :) – Cogwheel