elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Únete al Grupo Steam elhacker.NET


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Logaritmo sin librería Math.t
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: 1 [2] Ir Abajo Respuesta Imprimir
Autor Tema: Logaritmo sin librería Math.t  (Leído 10,467 veces)
do-while


Desconectado Desconectado

Mensajes: 1.276


¿Habra que sacarla de paseo?


Ver Perfil
Re: Logaritmo sin librería Math.t
« Respuesta #10 en: 2 Abril 2013, 11:43 am »

¡Buenas!

Creo que lo mas intuitivo es trabajar con la funcion inversa y aplicar Bolzano:

x = loga(b) -> ax = b -> ax - b = 0

Por lo tanto se trata de encontrar el cero de la función f(x) = ax - b

Aplicando un poco de analisis sabemos que ax es siempre positivo (siempre que a sea positivo), por lo tanto tal cero existirá si y solo si b es positivo.

En estas condiciones tendrás que buscar dos puntos x0 y0 en los que la función tenga signo distinto. Así sabrás que el cero de la función se encuentra entre estos dos puntos.

Solo te queda iterar. En cada paso tendrás que buscar el punto medio del intervalo y evaluarlo para saber si la función toma un valor positivo o negativo en dicho punto. Una vez sepas el valor de la función al evaluarlo en el punto medio podrás sustituir la cota superior o inferior que tenias inicialmente por el punto medio.

Este proceso parará cuando:
- La evaluación de la función en el punto medio de exactamente cero.
- La diferencia entre la cota superior e inferior sea menor a un valor que tu consideres un error aceptable para la solución del problema.
- Cuando entre una iteración y la siguiente no cambie el punto medio (esto sucede debido al incremento mínimo que existe en la representación interna de números en coma flotante)

El valor que devolverá la función logaritmo será el punto medio del intervalo en el que han acabado las iteraciones, ya que será el valor de x que ha hecho que la función f(x) = ax - b se aproxime mas a cero (el valor mas proximo a loga(b))

¡Saludos!


« Última modificación: 2 Abril 2013, 18:54 pm por do-while » En línea

- Doctor, confundo los números y los colores.
- Vaya marrón.
- ¿Marrón? ¡Por el culo te la hinco!
Puntoinfinito


Desconectado Desconectado

Mensajes: 919


#! /win/archlinux


Ver Perfil WWW
Re: Logaritmo sin librería Math.t
« Respuesta #11 en: 2 Abril 2013, 17:54 pm »

Hey! Tienes dos opciones, o copiar la función de log() directamente desde la librería math.h  :xD

Ó hacerlo de la siguiente manera;

Debes aplicar un algoritmo matemático y hacerlo de manera estándar.



Por lo tanto



Como ves se ha de pasar de un calculo logarítmico hacía uno exponencial.

Código:
log 10 (a) = ? ; 10[sup]x[/sup] = a

La x esta porque no sabemos el resultado de ese logaritmo, en caso de que lo tuviéramos sería tal como el ejemplo de la imagen anterior. Como no es así, elevamos una incógnita y factorizamos  a
. Imaginemos que a nos ha dado 5. Entonces, ahora tenemos 10x = 10[ sup]5[/sup]. Comparamos antes de factorizar y después de hacerlo y vemos que las bases son las mismas, entonces al ser las mismas las ignoramos y el número que nos ha la factorización es el resultante. x = 5

PD: Creo que era así


En línea

AHORA EN SOFTONIC || CLICK HERE!!
Base64: QWNhYmFzIGRlIHBlcmRlciAxIG1pbnV0byBkZSB0dSB2aWRhLiBPbOkh



HACK AND 1337 : http://hackandleet.blogspot.com
WEBSITE: http://www.infiniterware.
avesudra


Desconectado Desconectado

Mensajes: 724


Intentando ser mejor cada día :)


Ver Perfil
Re: Logaritmo sin librería Math.t
« Respuesta #12 en: 3 Abril 2013, 00:01 am »

Implementando de manera rápida lo que comentó @diskontrol que como he podido comprobar solo es válido para logaritmos en base 10, he sacado este código (seguro que es un churro, no me mateis   :( ). En cuanto lo último comentado por @Puntoinfinito eso solo vale para logaritmos exactos. ¿@do-while al fin y al cabo es ensayo y error no? Si yo tengo log24 -> 2x = 4 vas probando valores enteros hasta que tengas un resultado mayor que 4 o igual y vas reduciendo ... no sé tampoco tengo nivel matemático para hacerlo, implemente la serie de Taylor pero es muy lenta, dejo el código al que @diskontrol se refería:
Código
  1. #include <iostream>
  2. #include <sstream>
  3. #include <string>
  4.  
  5. using namespace std;
  6.  
  7. #define PRECISION 1000
  8.  
  9. #define e 2.7182818284590452353602874713526624977572470936999595749669676277240766303535
  10.  
  11. double ln (double num);
  12. double log10 (double num, std::string &str);
  13. double pow (double base, register int exp);
  14.  
  15.  
  16. int main(int argc , char * argv [])
  17. {
  18.    string str;
  19.    cout <<"Resultado en la precision maxima de de double es: "<< log10(34.4,str) << endl;
  20.    cout << "Resultado truncado a "<< PRECISION << " decimales es: " << endl<< str;
  21.    return 0;
  22. }
  23.  
  24. double pow (double base, register int exp)
  25. {
  26.    double ret = 1;
  27.    while(exp!=0)
  28.    {
  29.        ret = base*ret;
  30.        --exp;
  31.    }
  32.    return ret;
  33. }
  34. double ln (double num)
  35. {
  36.    string unused;
  37.    return (log10(num,unused)/log10(e,unused));
  38. }
  39. double log10 (double num,std::string &str)
  40. {
  41.    double ret = 0;
  42.    double decimal  = 0;
  43.  
  44.    if(num < 10)
  45.        num = pow(num,10);
  46.    else
  47.    {
  48.        while(num >= 10)
  49.        {
  50.            num /= 10;
  51.            ++ret;
  52.        }
  53.        num = pow(num,10);
  54.    }
  55.  
  56.    ostringstream convert;   // stream usado para la conversión.
  57.    convert <<ret;
  58.    str += convert.str();
  59.    str += '.';
  60.    for(register int i = 1 ; i != PRECISION; ++i)
  61.    {
  62.        while(num >= 10)
  63.        {
  64.            num /= 10;
  65.            ++decimal;
  66.        }
  67.        ret += decimal*(1/(pow(10,i)));
  68.        num = pow(num,10);
  69.  
  70.        str +=(char) decimal+48;
  71.        decimal = 0;
  72.    }
  73.    return ret;
  74. }
En línea

Regístrate en
diskontrol

Desconectado Desconectado

Mensajes: 89


RAWR!


Ver Perfil
Re: Logaritmo sin librería Math.t
« Respuesta #13 en: 3 Abril 2013, 03:08 am »

...IImplementando de manera rápida lo que comentó @diskontrol que como he podido comprobar solo es válido para logaritmos en base 10...
Puedes usarlo para cualquier base. No está en c, que así es más rápido, pero se entiende facil

Código
  1. function[x]=loga(num,basenum,baselog,decimales)
  2.    x=0;
  3.    for i=0:decimales
  4.        contador=0;
  5.        while num > baselog then
  6.            num=num/baselog;
  7.            contador=contador+1;
  8.        end
  9.        num=num^basenum
  10.        x=x+(contador/(10^i))
  11.    end
  12. endfunction

Código
  1. -->loga(12345,10,%e,4)
  2. ans  =
  3.  
  4.    9.421  
  5.  
  6. -->log(12345)
  7. ans  =
  8.  
  9.    9.4210064

Hay que usarlo con cuidado porque tiene limitaciones y no tiene en cuenta ni si quiera el dominio del logaritmo :-P
En línea

Siempre ten tus cosas cuando las necesites con @Dropbox. ¡Una cuenta de 2 GB es gratis! http://db.tt/YxRhsCI
do-while


Desconectado Desconectado

Mensajes: 1.276


¿Habra que sacarla de paseo?


Ver Perfil
Re: Logaritmo sin librería Math.t
« Respuesta #14 en: 3 Abril 2013, 11:13 am »

¿@do-while al fin y al cabo es ensayo y error no?

XD, si y no. Se puede considerar una especie de ensayo y error, pero aplicando la lógica. Después del primer paso conseguimos dos puntos x0, y0 en los que la función evaluada en el primero punto, en este caso en concreto, es menor que cero y evaluada en el segundo es mayor que cero:

                                                                      f(y0)



x0------------------------------------------------------y0 (eje OX)


f(x0)

Como la función es continua, si unes f(x0) y f(y0) con una linea, siempre tendrás que atravesar el eje OX. Es decir, en algún punto entre x0 e y0 la función sera cero. Ese es el punto que buscamos y sabemos que está entre ambos valores.

Por lo tanto obtenemos el punto z0 = (x0 + y0) / 2 y evaluamos la función en dicho punto. Imagina que sale que la función es positiva en z0:

                                                                      f(y0)

                                    f(z0)

x0---------------------------z0--------------------------y0 (eje OX)


f(x0)

Sigue sucediendo lo mismo de antes, entre x0 y z0 la función se anula, pero ahora tenemos un intervalo mas pequeño que el primero. Como z0 da un valor positivo, hacemos x1 := x0 e y1 := z0. Y aplicamos el proceso anterior al intervalo [x1,y1] para obtener un punto z1 que estará todavía mas próximo al cero de la función.

A fin de cuentas se trata de eso. De aproximar en cada paso cada vez mas el cero de la función dividiendo el intervalo de búsqueda en cada iteración. Si consideramos un error e, se tendrá que:

(y0 - x0) / 2n < e si y solo si

y0 - x0 < e 2n si y solo si

(y0 - x0) / e < 2n si y solo si

log2((y0 - x0) / e) < n

Es decir, como mucho tendremos que iterar una vez mas que la parte entera de log2((y0 - x0) / e) para obtener un resultado que se aproxime a la raíz con una precisión mayor que e/2.

¡Saludos!
« Última modificación: 3 Abril 2013, 11:18 am por do-while » En línea

- Doctor, confundo los números y los colores.
- Vaya marrón.
- ¿Marrón? ¡Por el culo te la hinco!
Páginas: 1 [2] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Libreria math.php « 1 2 »
PHP
Erik# 15 10,034 Último mensaje 25 Julio 2009, 22:01 pm
por SnakeDrak
Serial y logaritmo
Dudas Generales
FasterBit 1 4,029 Último mensaje 22 Octubre 2011, 15:25 pm
por Aberroncho
Libreria math.h
Programación C/C++
juancaa 3 4,088 Último mensaje 17 Marzo 2012, 21:39 pm
por theluigy13etv
Libreria Math de C fuera del Dev-C++ « 1 2 »
Programación C/C++
Saikilito 11 9,210 Último mensaje 2 Julio 2017, 01:29 am
por engel lex
raiz cubica sin libreria math
Java
ericklopez 3 3,724 Último mensaje 30 Marzo 2020, 04:07 am
por CalgaryCorpus
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines