Alforitmo singular
Por favor necesito ayuda con algoritmo: dice lo siguiente: Calcular la comisión de un vendedor de libros si recibe 10 $ por cada libro vendido, 20$ adicionales a partir del libro 11 y 40 $ más a partir del equipo 21, (realizar el algoritmo para calcular su comisión sin utilizar ninguna condición)
1 Respuesta
Respuesta de rolan2kn
1
1
rolan2kn, Soy Ingeniero en Ciencias Informáticas, alguna experiencia en...
Lo que quieres hacer, según lo entiendo es algo como lo siguiente...
10*X + 20*(X-10) + 40*(X-20)
Si POR es el total de libros vendidos, recibe 10*X pesos en total por los libros más 20 adicionales por cada libro a partir del 11 "20*(X-10)" más 40 por cada libro a partir del 21 o 40*(X-20)...
Eso es lo que entiendo yo.
10*X + 20*(X-10) + 40*(X-20)
Si POR es el total de libros vendidos, recibe 10*X pesos en total por los libros más 20 adicionales por cada libro a partir del 11 "20*(X-10)" más 40 por cada libro a partir del 21 o 40*(X-20)...
Eso es lo que entiendo yo.
Muchas gracias por responder pero eso fue lo primero que pensé pero si por ej. la cantidad de libros fuera 8 la expresión
10*X + 20*(X-10) + 40*(X-20)
Quedaría sin tener sentido, hablando aritmeticamente, 10*8+20*(8-10)+40*(8-20) es decir debe haber otra expresión que funcione para cuando la cantidad de libros es o menor de 10 o entre 10 y 20 o mayor
si podrías proponerme algo lo agradecería mucho
Atentamente.
Marlene
10*X + 20*(X-10) + 40*(X-20)
Quedaría sin tener sentido, hablando aritmeticamente, 10*8+20*(8-10)+40*(8-20) es decir debe haber otra expresión que funcione para cuando la cantidad de libros es o menor de 10 o entre 10 y 20 o mayor
si podrías proponerme algo lo agradecería mucho
Atentamente.
Marlene
Claro que tiene sentido si analizas que cdo restes X-10 no puedes vender -2 libros y cuando restes X-20 no puedes vender -12 libros por lo tanto al aplicar la fórmula eso debe darte 0 y por tanto te dará como resultado 80, te pido disculpas por no explicar esas cosas.
Muchas gracias, entiendo el punto, pero si no fuera muy atrevida me podrías ayudar en el planteamiento del algoritmo considerando lo que se nos pide, "No utilizar ninguna instrucción selectiva", de tal forma que obtengamos el correcto monto de comisión
Para lograr que x-y = 0 siendo x, y números naturales tal que y > x
No es suficiente con poner unsigned int (entero sin signo) porque los números en c/c++ no se representan como en la vida real, no puedes decir que van de [0, n] porque cuando desbordas los límites lo que hace es dar la vuelta, ejemplo:
Unsigned x = 0-1; // eso en vez de dar 0 da 4294967295 que es el máximo número que almacena un entero, o sea que dio la vuelta...
Luego de tanto analizar y buscar fórmulas se me ocurrió lo siguiente:
utilizar la raíz cuadrada (sqrt de math.h), que sucede que la función raíz sólo está definida para los números naturales >= 0 a no ser que estés trabajando con números complejos pero no es el caso, además en c/c++ esta función está implementada para números naturales, por tanto cuando tratas de hallar la raíz cuadrada de un número negativo sqrt(-1), da un mensaje de error Domain Error.
Bien, lo que podemos hacer es capturar dicho mensaje y cambiar el valor a cero.
Entonces la solución que te propongo se basa en las propiedades de las raíces y las potencias: que x = pow(sqrt(x), 2), o sea que la raíz cuadrada de x al cuadrado da como resultado x, entonces en teoría si el radicando es positivo debería dar como resultado el mismo radicando y si es negativo debería dar 0 como resultado, pero sucede el tema del error que te comentaba. Ahora bien, sólo nos quedaría capturar el error y cablearlo para que sea cero el resultado en vez de +NAN o +INF, existe en la librería math. H una función llamada int _matherr(struct _exception *e), que es llamada automáticamente cuando ocurre un error, lo bueno de todo esto es que se le da la oportunidad al programador de modificarla para manipular los errores como desee, lo que haremos es eso, capturar el error mediante esa función y la modificaremos para que devuelva 0.
A continuación está el ejemplo:
//---------------------------------------------------------------------------
#include <math.h> // biblioteca matemática : pow, sqrt y _matherr
/* estamos tratando de hacer que 10*X + 20*(X-10) + 40*(X-20) esté sólo definida para números naturales, esto significa que X-Y = 0 si Y > X */
int Comision(int cl) // método que calcula la comisión, cl es la cantidad de libros
{
float com = cl * 10.0f; // multiplicamos 10*X y lo asignamos a com
float y = pow(sqrt(cl - 10.0f),2); /* necesitamos restar cl-10 para esto nos valemos de las propiedades de las potencias y las raíces como comentaba, note que si ocurre un error de dominio porque cl < 10, se llamará automáticamente la función _matherr donde ocurre la magia que necesitamos */
com += 20.0f * y; /* efectivamente podemos seguir completando la fórmula al sumar a com 20*(cl - 10), y será igual a 0 cuando cl < 10 */
y = pow(sqrt(cl - 20.0f),2); /*tenemos una situación similar a la anterior*/
com += 40.0f * y;
return com;
}
int _matherr(struct _exception *e) /* función que se llama automáticamente cdo ocurre algún error en math.h */
{
errno = 0; /* errno es la variable de error del sistema la ponemos a cero para indicar que no hay error */
e->retval = 0; /* retval, atributo de la estructura exception que constituye el valor de retorno, lo ponemos a cero para garantizar que la variable y sea 0*/
return 1; /*returnamos 1 para indicar que el error fue tratado */
}
La implementación de _matherr tiene como riesgo que cualquier otro error de math. H en el resto del programa se maneje de esta forma. Pero ten en cuenta que todo fue hecho pensando en que tendrás sólo este código usando algo de math.h.
Otra cosa, yo sé que debe existir algo más elegante por ahí, una fórmula matemática o algo, pero te cuento que no la pude encontrar, me pase hasta las 11 de la noche y eso fue lo que salió (me lo tome a lo personal, je je), es una solución ingenieril que resuelve tu problema, si te enteras de algo más elegante te agradecería que me lo hicieras saber.
Otra cosa, eso sale muy sencillo con ciclos y eso, pero como los ciclos tienen condiciones de parada... no quise hacerlo por ahí.
No es suficiente con poner unsigned int (entero sin signo) porque los números en c/c++ no se representan como en la vida real, no puedes decir que van de [0, n] porque cuando desbordas los límites lo que hace es dar la vuelta, ejemplo:
Unsigned x = 0-1; // eso en vez de dar 0 da 4294967295 que es el máximo número que almacena un entero, o sea que dio la vuelta...
Luego de tanto analizar y buscar fórmulas se me ocurrió lo siguiente:
utilizar la raíz cuadrada (sqrt de math.h), que sucede que la función raíz sólo está definida para los números naturales >= 0 a no ser que estés trabajando con números complejos pero no es el caso, además en c/c++ esta función está implementada para números naturales, por tanto cuando tratas de hallar la raíz cuadrada de un número negativo sqrt(-1), da un mensaje de error Domain Error.
Bien, lo que podemos hacer es capturar dicho mensaje y cambiar el valor a cero.
Entonces la solución que te propongo se basa en las propiedades de las raíces y las potencias: que x = pow(sqrt(x), 2), o sea que la raíz cuadrada de x al cuadrado da como resultado x, entonces en teoría si el radicando es positivo debería dar como resultado el mismo radicando y si es negativo debería dar 0 como resultado, pero sucede el tema del error que te comentaba. Ahora bien, sólo nos quedaría capturar el error y cablearlo para que sea cero el resultado en vez de +NAN o +INF, existe en la librería math. H una función llamada int _matherr(struct _exception *e), que es llamada automáticamente cuando ocurre un error, lo bueno de todo esto es que se le da la oportunidad al programador de modificarla para manipular los errores como desee, lo que haremos es eso, capturar el error mediante esa función y la modificaremos para que devuelva 0.
A continuación está el ejemplo:
//---------------------------------------------------------------------------
#include <math.h> // biblioteca matemática : pow, sqrt y _matherr
/* estamos tratando de hacer que 10*X + 20*(X-10) + 40*(X-20) esté sólo definida para números naturales, esto significa que X-Y = 0 si Y > X */
int Comision(int cl) // método que calcula la comisión, cl es la cantidad de libros
{
float com = cl * 10.0f; // multiplicamos 10*X y lo asignamos a com
float y = pow(sqrt(cl - 10.0f),2); /* necesitamos restar cl-10 para esto nos valemos de las propiedades de las potencias y las raíces como comentaba, note que si ocurre un error de dominio porque cl < 10, se llamará automáticamente la función _matherr donde ocurre la magia que necesitamos */
com += 20.0f * y; /* efectivamente podemos seguir completando la fórmula al sumar a com 20*(cl - 10), y será igual a 0 cuando cl < 10 */
y = pow(sqrt(cl - 20.0f),2); /*tenemos una situación similar a la anterior*/
com += 40.0f * y;
return com;
}
int _matherr(struct _exception *e) /* función que se llama automáticamente cdo ocurre algún error en math.h */
{
errno = 0; /* errno es la variable de error del sistema la ponemos a cero para indicar que no hay error */
e->retval = 0; /* retval, atributo de la estructura exception que constituye el valor de retorno, lo ponemos a cero para garantizar que la variable y sea 0*/
return 1; /*returnamos 1 para indicar que el error fue tratado */
}
La implementación de _matherr tiene como riesgo que cualquier otro error de math. H en el resto del programa se maneje de esta forma. Pero ten en cuenta que todo fue hecho pensando en que tendrás sólo este código usando algo de math.h.
Otra cosa, yo sé que debe existir algo más elegante por ahí, una fórmula matemática o algo, pero te cuento que no la pude encontrar, me pase hasta las 11 de la noche y eso fue lo que salió (me lo tome a lo personal, je je), es una solución ingenieril que resuelve tu problema, si te enteras de algo más elegante te agradecería que me lo hicieras saber.
Otra cosa, eso sale muy sencillo con ciclos y eso, pero como los ciclos tienen condiciones de parada... no quise hacerlo por ahí.
- Compartir respuesta
- Anónimo
ahora mismo