Autor
|
Tema: Codigo fuente de la funcion pow de math.h? (Leído 12,137 veces)
|
prometheus48
Desconectado
Mensajes: 176
Making a Distro...
|
Hola,
Me gustaria hacer un programa que hiciera eso, elevar un numero base a una potencia, pero sin utilizar un bucle o la libreria math.h .
¿Alguien tiene el source code de la funcion pow?
¿O alguien sabe como hacerlo?
Salu2!
|
|
|
En línea
|
"Si tú tienes una manzana, y yo otra, y las intercambiamos, tu sigues teniendo una manzana, y yo sigo teniendo una manzana. Pero, si tu tienes una idea, y yo otra, y nos las intercambiamos, tu tienes dos ideas, y yo tengo dos ideas" The knowledge is free
|
|
|
eleon
Desconectado
Mensajes: 99
|
No sé cuál será el código en la librería "math.h" pero es tan sencillo como un bucle: #include <iostream> using namespace std; int main() { int x1, exponente, resultado; cout << "Base: "; cin >> x1; cout << endl << "Exponente: "; cin >> exponente; resultado = x1; if (exponente = 0) resultado = 1; else if (exponente = 1) resultado = x1; else { for (int i = 1; i < exponente; i++) { resultado *= x1; } if (exponente < 0) resultado = 1 / resultado; //Si el exponente es negativo... cout << endl << "Resultado: " << resultado; return 0; } }
Ahora mismo no tengo compilador para probarlo, pero creo que no tiene ningún error. Saludos. Edito: Vale, me doy cuenta de que faltaría modificar el matiz para un exponente negativo, voy a ver como sería y comento. Edito 2: Corregido, si el exponente es negativo basta con dividir 1 entre el resultado.
|
|
« Última modificación: 29 Enero 2012, 14:59 pm por eleon »
|
En línea
|
|
|
|
Akai
Desconectado
Mensajes: 823
|
@eleon: un pequeño apunte. A parte de utilizar enteros con lo cual dividir 1 entre el resultado de la potencia te va a dar un 0 como una casa, aportas un código que lo hace utilizando un bucle, cosa que prometheus48 intentaba evitar.
@prometheus48:
El source code de la función pow lo encontrarás entre el código fuente del compilador que utilices. Por otro lado, suena a ejercicio de clase o algo por el estilo. Para qué querrías hacer una potencia sin utilizar un bucle? Si eso mírate recursividad.
|
|
« Última modificación: 29 Enero 2012, 00:13 am por Akai »
|
En línea
|
|
|
|
Xandrete
Desconectado
Mensajes: 210
|
Edito: Vale, me doy cuenta de que faltaría modificar el matiz para un exponente negativo, voy a ver como sería y comento.
Edito 2: Corregido, si el exponente es negativo basta con dividir 1 entre el resultado.
Y te faltaría también el caso general de un exponente real. Lo cierto es que no me voy a currar una explicación muy detallada si no tengo la seguridad de que de verdad te interesa el caso general del exponente real (en mi solución entrarían polinomios de Taylor, por ejemplo, y no es algo sobre lo que me apetezca escribir después de medianoche sin la certeza de que no se lo van a pasar por el forro, xD). Si te interesa (y por alguna razón sigues queriendo reinventar la rueda), ya nos lo dirás. Por otro lado, el caso particular de los exponentes enteros es una chorrada (tanto iterativa como recursivamente). Con lo cual no trato de decirte nada malo, sino que encontrarás muchos ejemplos, tanto en este foro como en cualquier otro sitio web. Además, ya que quieres que no haya bucles en tu programa, has de saber que es muy fácil y muy mecánico convertir una función iterativa (que seguramente ya sabes como se haría para este caso) en una recursiva. Un ejemplo con el factorial: int factorial1(int n) { // Version iterativa int result = 1; for (int i = 2; i <= n; ++i) result *= i; return result; } int factorial2(int n) { // Version recursiva if (n < 2) return 1; else return n*factorial2(n-1); }
Sólo tienes que aplicar lo mismo en tu caso (si sólo contemplas potencias enteras). ¡Saludos!
|
|
|
En línea
|
|
|
|
prometheus48
Desconectado
Mensajes: 176
Making a Distro...
|
GRacias chicos, si me interesa. No es un ejercicio de clase, porque como he dicho ya varias veces tengo 14 años.
¿Qué porque quiero hacerlo sin bucle? Bueno, porque segun mi padre es AVSOLUTAMENTE IMPOSIBLE hacerlo sin bucle y sin funcion pow. ( mi padre no sabe programar pero sabe de lo que hablo porque de pequeño programó en BASIC ). Entonces es exactamente por eso.
El usuario que puso un comentario arriba, no me acuerdo el nombre lo siento, me interesa de lo que hablas... ¿POdrías explicar un poco?
Salu2!
|
|
|
En línea
|
"Si tú tienes una manzana, y yo otra, y las intercambiamos, tu sigues teniendo una manzana, y yo sigo teniendo una manzana. Pero, si tu tienes una idea, y yo otra, y nos las intercambiamos, tu tienes dos ideas, y yo tengo dos ideas" The knowledge is free
|
|
|
Anastacio
Desconectado
Mensajes: 111
|
A, otro programador joven. Pues yo tengo 13, y me estoy liando con este post.
El codigo que se puso arriba, no serviria solo en caso de que los exponentes fuesen 0 o 1, y todos los demas???
Nota, no entendi el ultimo codigo, no puedo entender la sentencia for, me cuesta un Peru. Alguien me explica plisssss
Saludos!!!!
|
|
|
En línea
|
You, stop to close my post, you were novice too!!!!!!!!!!!!
|
|
|
Ferno
Desconectado
Mensajes: 375
|
Nota, no entendi el ultimo codigo, no puedo entender la sentencia for, me cuesta un Peru. Alguien me explica plisssss
Saludos!!!!
Para entender ese tipo de códigos es mejor agarrar lápiz y papel y hacerse un cuadro de seguimiento del algoritmo con varios ejemplos, y uno se va dando cuenta. Sin embargo, al menos en el método iterativo, el código está mal. for (int i = 1; i < n; ++i) result *= i; /*Si se mantiene el pre-incremente (incrementar antes de entrar al for), entonces i debe comenzar en 1, y la condición de corte debe ser menor estricto (sino entraría al for cuando i = 6 y no daría el resultado correcto*/
for (int = 2; i <= n; i++) result *= i; /*Sino debe incrementarse posterior a cada ciclco*/
|
|
« Última modificación: 1 Febrero 2012, 14:51 pm por Ferno »
|
En línea
|
|
|
|
ghastlyX
Ex-Staff
Desconectado
Mensajes: 1.900
|
Respecto a lo de elevar a exponentes reales, si soy sincero no me lo había planteado y no sé la mejor manera de hacerlo. Si tuviera que programarlo ahora lo haría en términos de la definición usando variable compleja de la potencia, que es términos de la exponencial y del logaritmo y que por tanto implican (sin usar esas dos funciones) series de Taylor. Pero si tienes 14 años, entrar en series de Taylor puede ser algo duro, necesitarías probablemente mucha base matemática de cosas que no conoces. Respecto a lo que comenta Ferno, no sé por qué dices que está mal. Es lo mismo hacer for (int i = 1; i < n; ++i)
que for (int i = 1; i < n; i++)
El postincremento difiere del preincremento si se usa combinándolo con algo más, si no el resultado es equivalente. Como prueba simplemente hace falta considerar el siguiente código: #include <iostream> using namespace std; int factorial1(int n) { // Version iterativa int result = 1; for (int i = 2; i <= n; ++i) result *= i; return result; } int factorial2(int n) { // Version iterativa int result = 1; for (int i = 2; i <= n; i++) result *= i; return result; } int main() { int n; while (cin >> n) cout << factorial1(n) << " " << factorial2(n) << endl; }
Por ejemplo, la entrada Produce la siguiente salida: 1 1 1 1 2 2 6 6 24 24 120 120 720 720 5040 5040 40320 40320
|
|
|
En línea
|
|
|
|
Ferno
Desconectado
Mensajes: 375
|
Lo dije porque estaba seguro de que el pre-incremento justamente incrementaba la variable antes de llamar a las funciones del bucle for. Perdón entonces!
|
|
|
En línea
|
|
|
|
Xandrete
Desconectado
Mensajes: 210
|
GRacias chicos, si me interesa. No es un ejercicio de clase, porque como he dicho ya varias veces tengo 14 años.
¿Qué porque quiero hacerlo sin bucle? Bueno, porque segun mi padre es AVSOLUTAMENTE IMPOSIBLE hacerlo sin bucle y sin funcion pow. ( mi padre no sabe programar pero sabe de lo que hablo porque de pequeño programó en BASIC ). Entonces es exactamente por eso.
El usuario que puso un comentario arriba, no me acuerdo el nombre lo siento, me interesa de lo que hablas... ¿POdrías explicar un poco?
Salu2!
Tampoco hacía falta recordar mi nombre... lo podías copiar y pegar, xD. A ver, dile a tu padre que sí que se puede hacer sin bucle. Ejemplo; #include <iostream> using namespace std; int pow_aux(int b, int ex) { if (ex == 0) return 1; else return b*pow_aux(b,ex-1); } double pow(int b, int ex) { if (ex > 0) return pow_rec(b,ex); else return 1.0/pow_rec(b,-ex); } int main() { int a,b; cin >> a >> b; cout << pow(a,b) << endl; }
Y bueno, como te han comentado, hace falta tener base matemática para comprender como se haría en el caso del exponente real. Este es mi código: #include <iostream> #include <cmath> #include <vector> #define GRADMACLAURINSERIES 20 using namespace std; vector<double> PolyExp; vector<double> MacLaurinExp(int grad) { vector<double> Poly(grad+1); Poly[0] = 1; for (int i = 1; i <= grad; ++i) Poly[i] = Poly[i-1]/i; return Poly; } double evalPoly(double x, vector<double> Poly) { double result = 0; for (int i = Poly.size()-1; i >= 0; --i) result = result*x + Poly[i]; return result; } double pow_aux(int ex) { if (ex == 0) return 1; else return M_E*pow_aux(ex-1); } double pow(double b, double ex) { double result; ex *= log(b); if (ex > 0) result = pow_aux(int(ex)); else result = 1.0/pow_aux(int(-ex)); result *= evalPoly(ex-int(ex),PolyExp); return result; } int main() { double x,y; PolyExp = MacLaurinExp(GRADMACLAURINSERIES); cin >> x >> y; cout.precision(10); cout << pow(x,y) << endl; }
MacLaurinExp devuelve los coeficientes de la serie de MacLaurin (polinomio de Taylor en x=0) de la función exponencial (e x) en un vector. polyEval evalúa el polinomio para un valor de x mediante el algoritmo de Horner. En mi código, lo que hago básicamente es plantearme una potencia x y de la siguiente manera: e ln(x)*y (sólo funciona para bases mayores que 0, claro, para bases menores que 0 el resultado es, en general, complejo, y se tendría que calcular de otra manera). ln(x)*y consta de parte decimal y parte entera. Pongamos que ln(x)*y = 5.64. Como e 5.64=e 5e 0.64la serie de MacLaurin (polinomio de Taylor en x=0) de la función exponencial, lo que hago es evaluar e 5 de la manera tradicional (mediante bucles o mediante una función recursiva, como en este caso con pow_aux) y e 0.64 lo obtengo mediante el polinomio de Taylor de la función exponencial. Luego multiplico los dos resultados y listo, tengo x y. Insisto en que, para comprender esto, deberías saber lo que es el polinomio de Taylor de una función. Además, considerando que tu nivel de programación todavía no es muy alto, quizás deberías centrarte en seguir aprendiendo antes de preocuparte por estas cosas. EDITO: Oh, y M_E es una macro definida en cmath, que contiene el número e con la máxima precisión que admite la máquina. Saludos EI: juntando mensajes.Ah, aquí una implementación mucho más eficiente del algoritmo para exponentes enteros. Si bien en los algoritmos dados hasta ahora el coste era Θ(n), en éste el coste es Θ(log n), lo cual es una mejora MUY importante. #include <iostream> using namespace std; double pow_aux(double b, int e) { if (e == 0) return 1; else { double x = pow_aux(b, e/2); if (e%2) return x*x*b; else return x*x; } } double pow(double b, int e) { if (e < 0) return 1/pow_aux(b,-e); else return pow_aux(b,e); } int main() { double b; int e; cin >> b >> e; cout << pow(b,e) << endl; }
|
|
« Última modificación: 21 Febrero 2012, 17:00 pm por Eternal Idol »
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
Codigo Fuente
Ingeniería Inversa
|
popemonica
|
1
|
2,795
|
25 Octubre 2005, 01:06 am
por #Borracho.-
|
|
|
Software que analice el código fuente de un proyecto buscando codigo malicioso
Bugs y Exploits
|
murdock_
|
8
|
10,328
|
18 Agosto 2010, 01:14 am
por Erfiug
|
|
|
Extrayendo código fuente de una web (Problema con código generado por JS)
PHP
|
Littl3
|
4
|
8,479
|
3 Marzo 2011, 04:13 am
por Nakp
|
|
|
[DUDA] ¿Porque la función math me devuelve resultados erroneos?
Java
|
JollyRoyer
|
3
|
2,535
|
5 Marzo 2015, 18:54 pm
por Usuario Invitado
|
|
|
¿Cuál es la función de este código fuente?
Programación General
|
TheDemoniox
|
1
|
2,343
|
7 Febrero 2017, 17:33 pm
por Borito30
|
|