<br><br><div class="gmail_quote">El 4 de octubre de 2012 02:59, Davidson, Steven <span dir="ltr"><<a href="mailto:srd4121@njit.edu" target="_blank">srd4121@njit.edu</a>></span> escribió:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

Hola Santiago,<br>
<br>
2012/10/3 Santiago Tabarez <<a href="mailto:santiago230792@gmail.com">santiago230792@gmail.com</a>>:<br>
<div class="im">> Yo hace unos meses había empezado mi propio proyecto de una calculadora que<br>
> funcionara en línea de comandos (terminal).<br>
> En principio le había agregado las cuatro operaciones básicas, pero luego<br>
> les agregué otras, que son las funciones/macros contenidas en<br>
> el archivo cabecera cmath: pow, sqrt, sin, tan, cos, asin, atan, acos, log,<br>
> abs, asinh, acosh, atanh y algun otro más<br>
><br>
> Pero como yo quería aprender un poco más de matemática y fortalecer mis<br>
> conocimientos de C++ puro con un ejemplo que me hiciera usar<br>
> muchas de sus posibilidades, decidí hacer mis propias funciones de las<br>
> operaciones. Esto es lo que hice en cuanto a las 4 operaciones básicas:<br>
><br>
<br>
</div>[CORTE]<br>
<div class="im"><br>
> ... e hice estas operaciones hasta el momento:<br>
><br>
> double valor_absoluto (double x)<br>
> {<br>
>     if (x < 0) {<br>
>         return ((-x) * (2)) + (x);<br>
>     }<br>
><br>
>     return x;<br>
<br>
</div>El cálculo es demasiado complicado para algo tan sencillo como<br>
retornar: -x. Reescribiendo lo anterior, obtenemos,<br>
<br>
double valor_absoluto( double x )<br>
{<br>
  return x < 0.0 ? -x : x;<br>
<div class="im">}<br>
<br></div></blockquote><div><br>Tu implementacion me gustóo y luce más limpia. Si no te importa la voy a usar.<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div class="im">
> }<br>
><br>
> Quiero saber si estoy fallando en algo en esta operacion:<br>
><br>
> double potenciacion (int base, int exp)<br>
> {<br>
>     int iResult;<br>
><br>
<br>
</div>Esto ya va a suponer un problema, porque vas a retornar este resultado<br>
cuando indicas que el valor de retorno es de tipo 'double'. El otro<br>
problema es que 'int' no tiene un intervalo muy grande para la<br>
potenciación. Sugiero que la base sea 'double', y así puedes crear una<br>
función más genérica. Si dejas el exponente como un entero, entonces<br>
puedes emplear un algoritmo optimizado para calcular la potenciación<br>
con una complejidad temporal de O(lg n), donde 'n' es el exponente.<br>
<div class="im"><br>
>     if ((base != 0) && (exp == 0))<br>
>         iResult = 1;<br>
>     else if ((base == 0) && (exp > 0))<br>
>         iResult = 0;<br>
>     else if (exp == 1)<br>
>         iResult = base;<br>
<br>
</div>Esta última comprobación no es necesaria, ya que se puede tratar como<br>
el mismo caso general posterior.<br>
<div class="im"><br>
>     else {<br>
>         for (int iCounter = exp; exp > 1; iCounter--) (base * base);<br>
<br>
</div>Esto no tiene mucho sentido. La sentencia, 'base * base', no es<br>
consecuente al finalizar el bucle, ya que hace un cálculo, pero ignora<br>
el resultado. Sospecho que querías hacer esto:<br>
<br>
iResult *= base;<br></blockquote><div><br>Efectivamente quería hacer eso. Cuando escribí el email no presté mucha antención y lo envié tal y como lo viste. Segundos despues de enviado, revisé esta sentencia y me dí cuenta del error. <br>

 </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Sin embargo, necesitas dar un valor inicial a 'iResult'. Esto sería,<br>
<br>
for( iResult = 1; exp > 0; exp-- )  iResult *= base;<br>
<br>
Como puedes ver, no necesitamos crear otra variable para controlar<br>
este bucle, ya que podemos usar 'exp' directamente. También puedes ver<br>
que combinamos el caso anterior cuando el exponente es 0 (cero).<br>
<br>
Sin embargo, existe otro método para calcular la potenciación que se<br>
basa en multiplicar cuadrados de la base. El bucle se basaría en<br>
recorrer la secuencia binaria del exponente, y por tanto realizamos<br>
menos iteraciones. Si te interesa este otro algoritmo, dímelo y te lo<br>
doy.<br></blockquote><div><br>Claro, me gustaría saber cómo implementar este otro algoritmo. Hasta tal vez podría resultar más eficiente.<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">


<br>
>     }<br>
><br>
>     return iResult;<br>
> }<br>
><br>
<br>
Además, sugiero agregar otra comprobación que es cuando el exponente<br>
es negativo, ya que indicaría la inversa del resultado que se acaba de<br>
calcular.<br></blockquote><div><br>De esta otra comprobacion no me había dado cuenta, pero esto es lo que hice para tratar de aplicarlo:<br><br>double potenciacion (double base, int exp)<br>    // potenciacion<br>{<br>    double dResult;<br>

<br>    if ((base != 0) && (exp == 0)) // cualquier número elevado a la 0 potencia da 1 como resultado<br>        dResult = 1;<br>    else if ((base == 0) && (exp > 0)) // si la base es cero y el exponente distinto de cero, siempre dará como resultado cero<br>

        dResult = 0;<br>    else if ((exp < 0) && (base != 0)) // si la base es distinta de cero y el exponente negativo<br>        dResult = 1 / potenciacion (base, -exp);<br>    else {<br>        for (dResult = 1; exp > 0; exp--) // todos los demas casos<br>

        {<br>            dResult *= base;<br>        }<br>    }<br><br>    return dResult;<br>}<br><br>Pero hay un caso que es cero elevado a la cero potencia ( 0º ) que en principio sería indeterminado.<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">


<div class="im"><br>
> Así como está esta operacion, dependería de la anterior en que funcione<br>
> adecuadamente.<br>
><br>
> double calc_root (double base, double root)<br>
> {<br>
>     return potenciacion (base, 1 / root);<br>
<br>
</div>Esto no va a funcionar como esperas, aun teniendo la implementación<br>
correcta de la potenciación, ya que el exponente que pasas es de tipo<br>
'double', mientras que 'potenciacion()' espera un entero. Además,<br>
matemáticamente puedes ver que tu implementación no realizará una<br>
iteración parcial para que los cálculos salgan bien. O sea, si el<br>
exponente es 1/2, para la raíz cuadrada, tu algoritmo no va a realizar<br>
media iteración dando el resultado que quieres.<br>
<br>
La solución es implementar un algoritmo numérico, como por ejemplo, la<br>
expansión de la serie de Taylor, con a=1, o el método de<br>
Newton-Raphson ( <a href="http://es.wikipedia.org/wiki/M%C3%A9todo_de_Newton" target="_blank">http://es.wikipedia.org/wiki/M%C3%A9todo_de_Newton</a> ).<br>
Para terminar el método iterativo de Newton-Raphson, puedes comprobar<br>
un nivel de tolerancia entre el valor generado en la iteración actual<br>
y el valor de la iteración anterior.<br></blockquote><div><br>Actualmente estoy intentando ver cómo implementar el método de Newton-Raphson, que lo veo muy complicado. Por ahora voy a dejar las raíces de lado un tiempo.<br>

<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im"><br>
> }<br>
><br>
> En lo posible -a la amable persona que me asesore- si puede, que me de<br>
> pistas de lo que pueda estar fallando y de posibles errores en la<br>
> implementacion de C++.<br>
><br>
> Tambien agradezco a Steven Davidson por contestar mi duda acerca de un<br>
> ejemplo de internet que modifique.<br>
><br>
<br>
</div>De nada; para esto estamos :)<br>
<br>
<br>
Espero que todo esto te oriente.<br>
<br>
Steven<br>
<br>
_______________________________________________<br>
Lista de correo Cconclase <a href="mailto:Cconclase@listas.conclase.net">Cconclase@listas.conclase.net</a><br>
<a href="http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net" target="_blank">http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net</a><br>
Bajas: <a href="http://listas.conclase.net/index.php?gid=2&mnu=FAQ" target="_blank">http://listas.conclase.net/index.php?gid=2&mnu=FAQ</a><br>
</blockquote></div><br>Además creé una función que no esperaba crear, los factoriales. Utilicé valores de tipo <b>long double </b>dada la posibilidad de que los resultados puedan tomar valores muy grandes (el máximo valor al que devuelve un resultado es 170, luego de eso devuelve un "<b>1.#INF</b>"). Si hay algo mal avisame.<br>

<br>long double factorial (long double x)<br>    // cálculo de factoriales<br>{<br>    long double y = 1;<br><br>    while ( x > 1 ) {<br>        y *= x;<br>        x--;<br>    }<br>    return y;<br>}<br><br>Para finalizar quería agradecerle la asistencia y si puede por favor explíqueme los algoritmos que me había propuesto.<br>