4

Trivial question: I am just wondering, if one wants to raise an int or a long to the power of another int or long, does

(long)std::pow((double)a,(double)b)

suffice, or do I need

(long)(0.5 + std::pow((double)a,(double)b))

?

Cookie
  • 12,004
  • 13
  • 54
  • 83

7 Answers7

5

There are two considerations. The first is roundoff due to inexactness of floating point representations; this won't be a problem in this case, because integers are perfectly representable as long as the number of bits is less than the bits of significand in the floating point. If long is 32 bits and double significand is 53 bits, as it usually is, there won't be a problem.

The second consideration is the accuracy of the pow function itself. If there's any possibility that it will come out lower than the actual value, adding 0.5 to round the result is the only way to ensure the proper result.

The expected result of your pow will always be an integer, so there's no harm in adding 0.5. I'd recommend that version.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
3

You should write your own function. That way you can handle overflow yourself, and you don't have to worry about rounding errors.

But of the two I would use the second.

john
  • 85,011
  • 4
  • 57
  • 81
3

The second example may be more suitable as it rounds the result off to the nearest integer rather than truncates it.

AlexK
  • 1,279
  • 8
  • 19
2

Why not just use a loop. There can't be more than 31/63 integer multiplications without overflow anyway.

adrianm
  • 14,468
  • 5
  • 55
  • 102
  • One more own function in the code base I guess. Plus efficiency. But I agree that it is an option. – Cookie Aug 17 '11 at 14:16
  • Here is an implementation with only 5/6 multiplications. http://stackoverflow.com/questions/101439/the-most-efficient-way-to-implement-an-integer-based-power-function-powint-int/101613#101613 – adrianm Aug 17 '11 at 14:49
1

First one would be sufficient but you need to check the result double value before casting since it can be pretty larger than long's max.

Tae-Sung Shin
  • 20,215
  • 33
  • 138
  • 240
0

Your first example is valid. It would be best to use a static_cast<>() instead of a c-style cast for clarity however. The second example you posted would give an incorrect result for small values and is superfluous.

Ephphatha
  • 586
  • 2
  • 8
  • 1
    When would the second example yield incorrect results? And couldn't it happen in the first example that say 3 ^ 3 becomes 8.9999999999 and in the cast becomes 8? I don't expect this to happen for small numbers but once numbers become large, is this not a possibility? – Cookie Aug 17 '11 at 14:05
  • @myself: It would give wrong results for -ve a and odd b of course, but apart from that? – john Aug 17 '11 at 14:07
  • If you have a negative exponent or compute a power where the result is less than 1. Considering the result will be cast back to an integer value that's going to be a problem anyway. – Ephphatha Aug 17 '11 at 14:09
  • 2
    @Ephphatha: Less than 1 (and not 0) can't happen with ints or longs. – Cookie Aug 17 '11 at 14:11
  • @john: According to [here](http://stackoverflow.com/questions/605533/does-casting-to-an-int-after-stdfloor-guarantee-the-right-result) truncating is to neg infinity, not zero. So say -2 to 3, would be -7.9999 or -8.0001, becomes -7.5 becomes -8. – Cookie Aug 17 '11 at 14:12
  • @Cookie: std::floor truncates to negative infinity. You used a cast, which truncates to zero. – john Aug 17 '11 at 18:59
  • @john: I see. In that case a std::floor might be more appropriate? – Cookie Aug 18 '11 at 09:09
  • @Cookie: I think so, but don't take my word for it, write some test code and see for yourself. – john Aug 18 '11 at 09:43
0

It should be sufficient to do:

static_cast<long>(std::pow(static_cast<double>(a), b));

You should realise that this will overflow on large values of b.

Mankarse
  • 39,818
  • 11
  • 97
  • 141