jacknpoe

power(), ln() e exp() para números pequenos

Jul 3rd, 2025 (edited)
21
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.31 KB | Software | 0 0
  1. // power(base, expoente) usando exp (e elevado a x) e ln (logarítmo de x na base e) ambos com séries de Taylor
  2. // veja nos exemplos de power() as precisões, em casas decimais, porque essas séries são apemnas aproximações
  3. // são úteis em percentuais (<=5%) e número de períodos (<=120) triviais (quanto menores, maior a precisão)
  4. // power_int é uma função mais precisa, mas ela é para os casos em que a parcela/periodo é um número inteiro
  5. // ela também calcula com bases negativas (power() e ln() não foram projetadas para aceitarem bases negativas)
  6.  
  7. #include <iostream>   // cout
  8.  
  9. #define MAXEXP 20
  10. #define MAXLN 100
  11.  
  12. // essa função é especial para expoentes inteiros (optar por inteiros pode aumentar a precisão, a base pode ser negativa)
  13. double power_int(double base, long long expoente) {
  14.     if (expoente < 0) return power_int(1 / base, expoente * -1);
  15.     if (expoente == 0) return 1;
  16.     if (expoente % 2 == 0) return power_int(base * base, expoente / 2);
  17.     return base * power_int(base * base, (expoente - 1) / 2);
  18. }
  19.  
  20. // retorna a constante e elevada a uma potência double (é uma aproximação, verifique os exemplos de power() e testes)
  21. double exp(double x) {
  22.     double acumulador = 1.0, potencia = x;
  23.     long long fatorial = 1;
  24.     for(int indice = 1; indice <= MAXEXP; indice++) {
  25.         fatorial *= indice;
  26.         acumulador = acumulador + potencia / fatorial;
  27.         potencia *= x;
  28.     }
  29.     return acumulador;
  30. }
  31.  
  32. // retorna o logaritmo natural de um double (é uma aproximaçãom=, verifique os exemplos de power() e testes)
  33. double ln(double x) {
  34. //  if(x < 0.0) return 0.0;  // coloque aqui o que você quer que retorne quando x for negativo (por enquanto, apenas retorna absurdos)
  35.     if(x > 1.0 || x < -1.0) return ln(1 / x) * -1;  // || x < -1.0 não evita que o retorno não faça nenhum sentido
  36.     x -= 1;
  37.     double acumulador = 0.0, potencia = x;
  38.     long long sinal = 1;
  39.     for(int indice = 1; indice <= MAXLN; indice++) {
  40.         acumulador += sinal * potencia / indice;
  41.         sinal *= -1; potencia *= x;
  42.     }
  43.     return acumulador;
  44. }
  45.  
  46. // calcula base elevado a expoente, usando ln() e exp() (aproximação, veja a precisão dos exemplos abaixo e testes)
  47. // 6% ^ 5 = 15 casas, 3% ^ 60 = 15 casas, 3% ^ 120 = 7 casas, 5% ^ 60 = 7 casas, 5% ^ 120 = 3 casas, 10% ^ 60 = 3 casas
  48. double power(double base, double expoente) {
  49.     return exp(expoente * ln(base));
  50. }
  51.  
  52. // alguns testes
  53. int main() {
  54.     std::cout.precision(15);
  55.     std::cout << "2 ^ 3 = " << power_int(2, 3) << std::endl;
  56.     std::cout << "-3 ^ 5 = " << power_int(-3, 5) << std::endl;
  57.     std::cout << "-2 ^ 10 = " << power_int(-2, 10) << std::endl;
  58.     std::cout << "10 ^ 15 = " << power_int(10, 15) << std::endl;
  59.     std::cout << "1.03 ^ 5 = " << power_int(1.03, 3) << std::endl;
  60.     std::cout << "0.5 ^ 2 = " << power_int(0.5, 2) << std::endl << std::endl;
  61.     std::cout << "exp(1) = " << exp(1) << std::endl;
  62.     std::cout << "exp(-0.5) = " << exp(-0.5) << std::endl;
  63.     std::cout << "exp(-2) = " << exp(-2) << std::endl;
  64.     std::cout << "exp(3) = " << exp(3) << std::endl << std::endl;
  65.     std::cout << "ln(0.5) = " << ln(0.5) << std::endl;
  66.     std::cout << "ln(-0.5) = " << ln(-0.5) << std::endl;
  67.     std::cout << "ln(-2) = " << ln(-2) << std::endl;
  68.     std::cout << "ln(3) = " << ln(3) << std::endl << std::endl;
  69.     std::cout << "1.03 ^ 0.5 = " << power(1.03, 0.5) << std::endl << std::endl;
  70.     std::cout << "I 1.06 ^ 5 = " << power_int(1.06, 5) << std::endl;
  71.     std::cout << "D 1.06 ^ 5 = " << power(1.06, 5) << std::endl << std::endl;
  72.     std::cout << "I 1.03 ^ 60 = " << power_int(1.03, 60) << std::endl;
  73.     std::cout << "D 1.03 ^ 60 = " << power(1.03, 60) << std::endl << std::endl;
  74.     std::cout << "I 1.03 ^ 120 = " << power_int(1.03, 120) << std::endl;
  75.     std::cout << "D 1.03 ^ 120 = " << power(1.03, 120) << std::endl << std::endl;
  76.     std::cout << "I 1.05 ^ 60 = " << power_int(1.05, 60) << std::endl;
  77.     std::cout << "D 1.05 ^ 60 = " << power(1.05, 60) << std::endl << std::endl;
  78.     std::cout << "I 1.05 ^ 120 = " << power_int(1.05, 120) << std::endl;
  79.     std::cout << "D 1.05 ^ 120 = " << power(1.05, 120) << std::endl << std::endl;
  80.     std::cout << "I 1.1 ^ 60 = " << power_int(1.1, 60) << std::endl;
  81.     std::cout << "D 1.1 ^ 60 = " << power(1.1, 60) << std::endl << std::endl;
  82.     std::cout << "I -1.1 ^ 60 = " << power_int(-1.1, 60) << std::endl;
  83.     std::cout << "D -1.1 ^ 60 = " << power(-1.1, 60) << std::endl << std::endl;
  84.     system( "PAUSE");
  85. }
  86.  
Tags: Power exp pow LN
Add Comment
Please, Sign In to add comment