6

I am using the pow function in C and storing the return value in an integer type. see the code snippet below:

for (i = 0; i < 5; i++){
    val = (int)pow(5, i);
    printf("%d, ", val);
}

here i, and val are integers and the output is 1, 5, 24, 124, 624. I believe this is because a float 25 is treated as 24.99999... which gets rounded down to 24 on assignment to an integer.

How can I by pass this if I still need to store the return value in an int ?

xanatos
  • 109,618
  • 12
  • 197
  • 280
ango
  • 829
  • 2
  • 10
  • 23
  • `float` 25 isn't "treated as" `24.9...`, 25 can be exactly represented as a float. It's just that `pow` isn't completely accurate, and for some reason on this occasion has missed low. For many values it can't possibly be completely accurate, since the mathematically correct answer isn't an exact float, but for these calculations it could be, and so it's a quality-of-implementation issue whether or not it is. – Steve Jessop Oct 29 '11 at 08:36
  • 1
    See also http://stackoverflow.com/questions/101439/the-most-efficient-way-to-implement-an-integer-based-power-function-powint-int for discussion of how to implement an integer version of pow() – Salvatore Previti Oct 29 '11 at 11:11
  • Don't use `pow` for integer exponentiation. There are much better, safer ways. By the way, what platform are you getting this behavior on? I thought a good `pow` would always be exact for integers where the exact result fits in `double`. – R.. GitHub STOP HELPING ICE Oct 29 '11 at 12:15
  • Possible duplicate of [Strange behaviour of the pow function](https://stackoverflow.com/questions/18155883/strange-behaviour-of-the-pow-function) – Antti Haapala -- Слава Україні Jul 22 '17 at 09:04
  • Possible duplicate of [Why does pow(n,2) return 24 when n=5, with my compiler and OS?](https://stackoverflow.com/questions/25678481/why-does-pown-2-return-24-when-n-5-with-my-compiler-and-os) – phuclv Jul 31 '17 at 01:33

4 Answers4

9

Add 0.5 before casting to int. If your system supports it, you can call the C99 round() function, but I prefer to avoid it for portability reasons.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Marcelo Cantos
  • 181,030
  • 38
  • 327
  • 365
  • 3
    There's a slight difference, that `round` rounds away from zero, whereas adding 0.5 and casting to `int` rounds up. So for example `round(pow(-0.5,1))` is -1, whereas `(int)(pow(-0.5,1) + 0.5)` is 0. So questioner may need to decide which they want, although of course if the answer is close to an integer it makes no difference. – Steve Jessop Oct 29 '11 at 08:32
  • "round rounds away from zero, whereas adding 0.5 and casting to int rounds up" - for half-integer values, I mean. – Steve Jessop Oct 29 '11 at 08:39
  • @JoelSpolsky: Thanks for the edit, but `round()` isn't supported on all systems. I've qualified your edit accordingly. – Marcelo Cantos Oct 29 '11 at 11:15
  • @Joel: I think you were right. `round()` is standard (C99), it's just that some systems aren't. It's sometimes necessary to program to C89, but if a function is in C99 then all you have to worry about is primitive systems with very old compilers. Windows being the example that most often matters. – Steve Jessop Oct 31 '11 at 09:34
  • @SteveJessop: Well-spotted (answer amended). – Marcelo Cantos Oct 31 '11 at 09:53
5

replace

val = (int)pow(5, i);

with

double d = pow(5,i);
val = (int)((d > 0.0) ? floor(d + 0.5) : ceil(d - 0.5));
AndersK
  • 35,813
  • 6
  • 60
  • 86
4

Implement pow yourself.

int myPow(int base, int exponent) {
    int n = 1;
    for (int i = 0; i < exponent; i++) {
        n *= base;
    }
    return n;
}

This, of course, only handles positive exponents, and only works on ints, and there are certainly more efficient ways to do it. See, for example, the source for ^ in Haskell.

Dan Burton
  • 53,238
  • 27
  • 117
  • 198
-3

I had this problem my self. I solved it easily in your instruction simply just add if statement.

if (k%n>0)
{
    k=k+1;
}
phuclv
  • 37,963
  • 15
  • 156
  • 475
Benas
  • 1
  • 1
  • 6