-6

I implemented my own power function, which I further used for calculating a root. I wanted to compare the result returned by my function, with the one returned by the pow function, from the math.h. However, it turned out, when using my power function for calculating roots, it yields wrong answers. The square root of 15 is about 3, but my code prints 15:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>

double power(int base, double index)
{
    double result = 1;
    int i;

    for (i = 0; i<index; i++)
        result *= base;

    return result;
}

int main()
{
    int n = 15, s = 2;

    printf("2^3 = %f\n\n", power(2,3));

    double result1 = power(n, 1.0/s);
    printf("%d\n", (int)result1);

    double result2 = pow(n, 1.0/s);
    printf("%d\n", (int)result2);

    return 0;
}
darias
  • 247
  • 1
  • 3
  • 10
  • 5
    This isn't a coding issue, rather an algorithmic one. The algorithm you have used for `power` only works for integer `index`. – R_Kapp Feb 18 '16 at 14:42
  • At the level of mechanism, it's because for a base of 1 and an exponent of 1/2, what you're doing is simply multiplying 1 by 1 and then returning that as a result. At the level of mathematics, it's simply because you don't calculate a square root like that. – Theodoros Chatzigiannakis Feb 18 '16 at 14:43
  • @R_Kapp: Changing `int` to `double` does not solve the issue, the answer is now 15 – darias Feb 18 '16 at 14:43
  • So how to use my own `power` function to calculate the same thing I did with the `pow`? – darias Feb 18 '16 at 14:44
  • You really should compile with all warnings and debug info (`gcc -Wall -Wextra -g` if using [GCC](http://gcc.gnu.org/)) and **use the debugger** (e.g. `gdb`) to run your program step by step. – Basile Starynkevitch Feb 18 '16 at 14:45
  • I said the issue was algorithmic; this means there is no easy way to "fix" the syntax and get the right answer. Read [this](http://stackoverflow.com/questions/1375953/how-to-calculate-an-arbitrary-power-root) Q&A for more info. – R_Kapp Feb 18 '16 at 14:45
  • 2
    I believe it's a bit complicated to create a `pow` function. Look at [an actual implementation](http://opensource.apple.com/source/Libm/Libm-315/Source/ARM/powf.c) and see if you can figure out how it works. – Theodoros Chatzigiannakis Feb 18 '16 at 14:46
  • How could this possibly do what you want if `index` is a non-integer? It makes no sense. For non-integer exponents, you need something like `exp(index*log(base))`. – Tom Karzes Feb 18 '16 at 14:48
  • @darias: I have to ask; are you trolling? There is such a disparity between the question presentation quality and the concept. You must have tried a debugger, surely? – Bathsheba Feb 18 '16 at 14:48
  • 1
    I'm voting to close this question as off-topic because this is just a very strange question, – Bathsheba Feb 18 '16 at 14:49
  • I hope you're correct. But any examination of `power` reveals the reason. – Bathsheba Feb 18 '16 at 14:50

1 Answers1

1

Your function didn't work because its implementation uses a method that's typically used for explaining powers intuitively ("take the number 1 and multiply it exponent times by the base"). However, that method is only applicable for natural numbers. It is not the actual mathematical definition for powers with arbitrary exponents.

If you want to have a function that works for other number spaces, you need to find a numerical method that's applicable for those those as well. Typically, those involve calculating a particular series.

First, you need to define a function that handles these:

  1. Power for exponents that are positive integers. (This is what you have achieved.)
  2. Power for exponents that are negative integers. (You could use inversion, abs and your previous step for this.)
  3. Power for exponent equal to zero. (Luckily, this is just a constant for most cases.)

You will also need an already-implemented ln(double x) (or you can implement it by summing a particular series that will involve your integer power function) and a factorial(int n) function (it's easy to write this, even intuitively).

Then, you can write a function that takes any real base, and any real exponent and an integer n and do these:

  1. Calculate exponent * ln(base).
  2. Use your integer power function to calculate the n-th power of that result.
  3. Divide that result by factorial(n).

Wrap this in a loop that sums the results of this calculation for all values of n from 0 up until the highest that can be handled validly and efficiently (the higher the maximum n, the better the approximation). That sum is the mathematical result you're looking for. Therefore, a function that takes base and exponent as parameters and runs the aforementioned loop for a series of values of n is your actual final pow function that you can expose to external code.

Alternatively, it wouldn't hurt to just look at real-world implementations and see what methods they've used. Such implementations are often different from the most obvious mathematical ones, because they can be more efficient for computers (often directly taking into account the binary representations of the numbers involved) and also take special care to avoid things like overflows and underflows of the various data types involved.

Community
  • 1
  • 1
Theodoros Chatzigiannakis
  • 28,773
  • 8
  • 68
  • 104