C ++ или C Pow дает неправильный результат - PullRequest
1 голос
/ 20 марта 2012

я пытаюсь сделать свой собственный пау, но я получаю неправильный результат

я получаю: 2 ^ 3.3 = 16, что неправильно ... почему?

#include <iostream>

using namespace std;

double new_pow(double base, double power){

double result = 1;

for(int i = 0; i <= power; i++) {
    result *= base;
}


    return result;
}



int main (int argc, char * const argv[]) {

    std::cout << new_pow(2,3.3) << endl;
    return 0;
}

Пожалуйстапомогите найти ошибку

Ответы [ 5 ]

5 голосов
/ 20 марта 2012

Ошибка в том, что ваш цикл выполняется 4 раза, поскольку он не будет больше 3,3 за 4 итерации. Вот почему возведение в степень с плавающей запятой осуществляется с логарифмами, а не с повторным умножением.

3 голосов
/ 20 марта 2012

В ответе Игнасио уже упоминалось использование логарифмов. Но в конечном итоге мы используем exp(), что опять-таки является библиотечной функцией. Так что, если вы вообще не хотите использовать библиотечные функции, вам придется прибегнуть к чему-то вроде расширения Тейлора из x^y

Поскольку прямая оценка расширения Тейлора для x^y является утомительной, как упомянул Игнасио, base^power = exp( power*ln(base) ). И разложение Тейлора для e ^ x довольно просто, а для ln (x) также очень просто. Оба они дают простую интерактивную / рекурсивную реализацию в C

Вот простая реализация e^x с использованием вышеупомянутого расширения Тейлора

double pow_x ( double x , unsigned i )
{
       double prod=1;
       if ( i == 0 )
          return 1;
       while ( i )
       {
             prod*=x;
             i--;
       }
       return prod;
}

long long factorial ( unsigned n )
{
     if ( n == 0 )
        return 1;

     return n * factorial (n-1);
}

double expo ( double x, int terms )
{
       /* terms tells us how long should we expand the taylor's series */
       double sum=0;
       unsigned i=0;
       while ( i< terms )
       {
             sum+= pow_x(x,i)/factorial(i);
             i++;
       }
       return sum;
}

exp(5.93,20) дает 376.152869, с чем Google стремится согласиться.

Надеюсь, используя этот пример, вы можете реализовать ln(x) самостоятельно.

0 голосов
/ 20 марта 2012

Вы зацикливаетесь, рассматривая power как int. Цикл будет запущен 4 раза и вернет 2^4 = 16.

Как приблизить десятичные показатели, используя логарифмы .

0 голосов
/ 20 марта 2012
for(int i = 0; i <= power; i++)

должно быть

for(int i = 1; i <= power; i++)

В противном случае он будет выполняться за одну дополнительную итерацию.

Как уже упоминалось в ответе Игнасио Васкеса-Абрама.Предположим, вы хотите, чтобы мощность у = х ^ б.Это эквивалентно ln (y) = b * ln (x).

, поэтому y = exp(b*ln(x))

y = Math.e(b*Math.Log(x)) //Java
0 голосов
/ 20 марта 2012

Поскольку вы увеличиваете i на 1., поэтому после 4.0 оно будет напрямую увеличено до 5.0, что делает проверку состояния цикла ложной и, таким образом, прерывает цикл.

Кроме того, ваше начальное значение для переменной цикла равно 0, поэтому вы должны проверить это следующим образом -

for(double i=0; i<power; i++)

Вы можете взглянуть на этот ответ, чтобы получить представление о том, как реализовать возведение в степень с плавающей запятой, и здесь для его довольно высокого уровня реализации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...