[ Foro de C ]
Necesito ayuda con la siguiente función. Fuera de Firebird funciona perfectamente,
pero dentro de la base de datos sólo muestra decimales.
__declspec(dllexport) __cdecl double ib_redondear(float num)
{
double retorno;
float decimal;
decimal=num-floor(num);
if (decimal > 0 && decimal <=0.25 ) {
retorno= floor(num)+0.25;
} else if
(decimal > 0.26 && decimal <=0.50 ) {
retorno=floor(num)+0.5;
} else if (decimal > 0.51 && decimal <=0.75 ) {
retorno=floor(num)+0.75;
} else if (decimal > 0.76 && decimal <=1 ) {
retorno=floor(num)+1;
}
return retorno;
}
Para quien me pueda ayudar gracias.
No entiendo eso de "sólo muestra decimales", ni eso de "fuera de Firebird"... ¿los programas de prueba que haces sin Firebird son exactamente para la misma plataforma?
Porque puede que si los pruebas en entornos distintos, uno de ellos muestre "coma" para separar los decimales y el otro muestre un "punto", y eso puede ser una fuente de problemas de conversión. Pero sin más detalles, me cuesta saber si es eso...
Gracias por contestar.
La cuestión es la siguiente: necesito incorporar una función definida por el usuario en la base de datos, que redondee un número según su parte decimal caiga en alguno de estos 4 intervalos: [num>0 , num<=0.25], [num>0.25 , num<=0.50], [num>0.50 , num<=0.75], [num>0.75 , num<=1.0].
A la función en cuestión (que es una dll), la he probado en una aplicación de consola que solicita un número y llama la función ib_redondear, mostrando correctamente los valores redondeados.
Pero cuando la incluyo en la base de datos, sólo me muestra como resultado el valor 0.25 para todos los valores de la tabla.
No había tenido en cuenta la cuestión del "." y la ",", entendiendo aunque la representación pueda diferir según el idioma del s.o., internamente no influye, pero de todos modos, acabo de probarlo y me sigue arrojando el mismo resultado de 0.25.
A esta altura, me tiene intrigada el por qué de los resultados, y seguiré intentando resolver el problema. Si lo logro, postearé la solución, aunque no me vendría mal una ayudita :).
Otro tema: intenté darme de alta en el foro, pero nunca llegó a mi mail el mensaje para activar la cuenta, por lo tanto no puedo ingresar. Agradeceré sugerencias.
¿No puedes depurar, para que la aplicación que conecte a la base de datos te muestre los datos en consola o los guarde en un fichero, y así puedas comprobar si todo lo que llega a Firebird está en formato correcto o si consigues ver algún error sintáctico que esté haciendo que los datos no se analicen bien?
Quizá te baste con eso: volcar datos a un fichero, para luego intentar reproducir esos pasos desde fuera de tu programa (con algún interfaz de administración de Firebird) y ver si en algún momento te marca algún paso como incorrecto.
Finalmente he logrado efectuar el redondeo. Para ello tuve que cambiar el enfoque de la función, y la reescribí para que recibiendo la parte decimal,
devuelva la diferencia a 0.25, 0.50, 0.75, y 1.0.
En firebird puede usar de la siguiente forma:
select cod, costo, preciopub,preciopub+ib_redondeodec(preciopub-floor(preciopub))
from preciosestela_mod;
La diferencia con el código anterior es que utilicé punteros y paso de valores por referencia.
El código quedó así:
__declspec(dllexport) float* __cdecl ib_redondeodec(float *dec)
//devuelve la diferencia en decimales
{
float *ret;
ret = (float*)malloc(sizeof(float) );
*ret=*dec;
if (*dec >0.00 && *dec <= 0.25) {
*ret= 0.25-*dec;
} else if (*dec > 0.26 && *dec <=0.50 ) {
*ret=0.5-*dec;
} else if (*dec > 0.51 && *dec <=0.75 ) {
*ret=0.75-*dec;
} else if (*dec > 0.76 && *dec <=1 ) {
*ret=1-*dec;
}
return ret;
}
//* End ib_redondeodec() ***
Curioso. No habría esperado que fuera necesario pasarlo por referencia, pero suena razonable que esa fuera la fuente del problema y que por eso los datos se interpretaran mal. Enhorabuena por conseguirlo!
(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)