2
int n;
n = 2;
int d;
d = pow(10,n);
cout<<d<<endl;

It displays 99 instead of 100. I have indcluded math.h

dau_sama
  • 4,247
  • 2
  • 23
  • 30
Dhruv Sb
  • 33
  • 5
  • try `powl` instead of `pow` – Manthan Tilva Aug 16 '16 at 04:12
  • 2
    Could you post the entire program? This returns 100 for me. – DarmaniLink Aug 16 '16 at 04:37
  • It's a combination od `using namespace std;` and mingw. I've never been able to figure out why this happens, but something goes funny with `std::pow`. Ran into this one here: http://stackoverflow.com/questions/33187956/c-pow-unusual-type-conversion/33190014#33190014 – user4581301 Aug 16 '16 at 04:51
  • powl is working but still can't figure out why pow is not working. In the same case if I write pow (10 , 2) it returns 100 but using the variable n it returns 99. – Dhruv Sb Aug 16 '16 at 05:02
  • You aren't calling `pow`. You're calling `std::pow`. – user4581301 Aug 16 '16 at 05:06
  • I removed using namespace std still it's 99 – Dhruv Sb Aug 16 '16 at 05:15
  • That's interesting. 100 should be perfectly representable by `double`, so you shouldn't have problems with it converting to something like to 99.9999999999 and getting truncated when assigning it to an `int`. The core of the problem is covered here: https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html but I'm not sure it would apply to this case. – user4581301 Aug 16 '16 at 05:23
  • What version number do you get when you type `g++ -v` into a terminal? – user4581301 Aug 16 '16 at 05:25
  • It returns 100: http://coliru.stacked-crooked.com/a/1a1947eea34c7d44 – plasmacel Aug 16 '16 at 06:06
  • Please update your question with the name and version of your compiler. Your problem must be a wrong compiler setting or compiler bug. What is the result when you try `double d = pow(10,n)` instead of `int d = pow(10,n)`? – plasmacel Aug 16 '16 at 06:12
  • http://i.stack.imgur.com/iXPpb.png – Dhruv Sb Aug 16 '16 at 08:49
  • 2
    @user4581301: According to IEEE754, non-trivial functions may have unspecified rounding errors (due to intermediate results). Only +-*/ and `sqrt` are guaranteed to be correct down to the Least Significant Bit. – MSalters Aug 16 '16 at 13:05
  • @MSalters That makes too much sense. Dhruv Sb, one side note: `pow` is a very expensive operation designed to handle the weird cases like pi to the power of e. For an integer taken to the power of an integer, you are usually better off looping and multiplying. If the power is known at compile time, odds are good the compiler will optimize out the loop. If the speed matters, profile to see what works better for your case. – user4581301 Aug 16 '16 at 14:29
  • @user4581301 : It's actually not so bad; `pi ^e` is just `2 ^ (e * log2(pi))`. You just convert everything to base-2 operations, and that's already the natural base for `double`. That said, for integers the best solution is generally `X^Y = (X*X)^(Y/2) [even Y] | X * (X*X)^(Y-1)/2 [odd Y]`. – MSalters Aug 16 '16 at 14:42
  • This is interesting. I've asked another question "Best or most efficient way to calculate power in c++" http://stackoverflow.com/questions/38978847/best-or-most-efficient-way-to-calculate-power-in-c – Dhruv Sb Aug 16 '16 at 15:29

1 Answers1

7

Quite possibly a rounding issue.

Some implementations of std::pow have special cases for integral arguments. Others just rely on basic math. For instance, pow(x,y) == pow(2, y*log2(x)). The typical reason why an implementation would use this rule is it represents floating-point numbers internally in base 2. But log2(x) may suffer from rounding issues.

In your case, log2(10) would be 3.3219280948873623478703194294894. That means that pow(10.0, 2.0) can be calculated behind the scenes as pow2(6.6438561897747246957406388589788) = 64 * pow2(0.6438561897747246957406388589788). It's quite possible that the latter term is rounded down, to a value just below the correct 1.5625.

MSalters
  • 173,980
  • 10
  • 155
  • 350