Tal vez me fumé mucho ya, pero juro que o he enloquecido, o encontré un bug bastante groso.
Encontrado en varias versiones. Actualmente uso la 4.088.Un error en la función pow(x,y) de la librería math.h:
Hacer esto:
float32 out;
printf("El resultado es: %f",out
);
arroja como resultado: -4.00
No he tenido tiempo de analizar la solución, pero el problema es claramente visible en la librería math.h:
//////////////////// Power functions ////////////////////
////////////////////////////////////////////////////////////////////////////
// float pow(float x,float y)
////////////////////////////////////////////////////////////////////////////
// Description : returns the value (x^y)
// Date : N/A
//
float32
pow(float32 x
,float32 y
){
if(x>=0)
else
}
Si analizamos la condicion del IF tenemos que
si x<0 entonces,
return( -(exp(y*log(-x))) );
pero como x<0, entonces hacer eso es lo mismo que hacer:
return( -exp(y*log(x)) );
porque como x era menor a cero, los signos negativos se cancelan quedando x positiva...
si nos fijamos, en realidad lo obtenido no es mas que el resultado para x>=0 pero con distinto signo final.
Entonces, podriamos simplificar diciendo que la funcion hace esto:
Sea Q(x,y)=exp(y*log(x) ) una funcion que devolvera supuestamente el valor absoluto1 de la funcion powsi x>=0 entonces
devuelve Q(x,y)
sino
devuelve -Q(x,y)
Vamos a ver en detalle el error ahora que se ha simplificado el algoritmo a sólo un cambio de signo según el signo de x.
para x=-2 e y=2
por ser x<0, entonces devolverá -Q(x,y). Asumiendo que Q(x,y) no tiene bugs y devuelve el valor absoluto
1 correctamente, nos quedaría que Q(x,y) da 4.
Ahora, al aplicarle el signo menos, tenemos el terrible bug, quedando finalmente como resultado -4.
Analizando un poco más el algoritmo, observamos que
el error sólo se produce cuando la base es negativa y el exponente, par. Es evidente que el algoritmo falla, porque sólo considera el signo de la base, pero no tiene en cuenta si el exponente es par o impar. No analice el caso de exponentes fraccionales.
¿Qué les parece?
Aclaraciones:1Podemos asegurar que Q(x,Y) devuelve siempre un valor mayor o igual a 0, porque si la analizamos:
Q(x,y) = exp(y*log(x) )
podríamos hacer una función compuesta, quedando:
Q(x,y) = exp(P(x,y))
donde P(x,y) = y*log(x)
Ahora, siendo que la funcion exp es e^x, y recordando que e es un número positivo, sabemos que no hay manera que e^P(x,y) de un resultado negativo.
Analizandolo si se necesita, tenemos que:
si P(x,y)>0, entonces el resultado será mayor a 0;
si P(x,y)=0, entonces el resultado será 1;
si P(x,y)<0, entonces el resultado será también mayor a 0; ya que e^(-P(x,y)) = 1/(e^P(x,y)) que es siempre positivo.
Queda demostrado entonces que Q(x,y)=exp(y*log(x) ) es siempre positivo,por lo que podríamos decir que devuelve el valor absoluto del resultado.