0

I'm working on CSES number spiral problem and I've noticed that c++ isn't calculating it right?

ans = pow(y, 2) - (x-1);

This is the code and I have x and y both set as 1000000000.

cout << "pow =" << pow(y, 2) << "\n";
cout << "x-1 =" << (x - 1) << "\n";

I've put this right before the calculation and pow shows up correct with 1e18 and x-1 is also correct with 999999999.

cout << 1000000000000000000 - 999999999 << "\n";

If I manually write it like this it works but pow(y,2) - (x-1) doesn't. It will give me an answer of 999999999000000000.

  • 1
    both x and y are long long data types if thats what you're referring to – Redminedevil Jul 23 '20 at 22:15
  • 4
    pow() is not for integers. its a floating point function. – drescherjm Jul 23 '20 at 22:15
  • 2
    For `pow(y, 2)`, prefer multiplication, such as `y * y`, as it will be more accurate and faster. Some compilers may be able to perform this substitution at higher optimization settings. – Thomas Matthews Jul 23 '20 at 22:18
  • Ah thank you! It calculates it correctly once i change ans to long double! I will definitely do y*y from now on – Redminedevil Jul 23 '20 at 22:20
  • @ThomasMatthews The compiler is not allowed to optimize in ways that change the observable behavior. In OP's case replacing `pow(y, 2)` with `y * y` would change the end result. – dxiv Jul 23 '20 at 22:22
  • Using `pow(x,2)` to square a number is like using a sledgehammer to push in a tack. – wcochran Jul 23 '20 at 22:23
  • 1
    @dxiv Please enlighten me as to how `pow(y,2)` differs from `y * y`. I thought this was a fundamental definition in mathematics of exponentiation. – Thomas Matthews Jul 23 '20 at 22:24
  • @ThomasMatthews This is C++ not math ;-) I did not say that the optimization is never possible, just that the compiler *must* prove it doesn't change the end result - and that's not always the case. There are more examples of counter-intuitive floating-point behaviors in the question linked as a duplicate. – dxiv Jul 23 '20 at 22:28
  • `pow()` is a very sophisticated math function that can do a lot of things like square roots `pow(x,0.5)` ... take a look at https://github.com/lattera/glibc/blob/master/sysdeps/ieee754/dbl-64/e_pow.c to see an implementation. You don't need to do all that to square a number. – wcochran Jul 23 '20 at 22:32
  • Many large integers can not be represented as a float, e.g., 16,777,217. https://stackoverflow.com/questions/3793838/which-is-the-first-integer-that-an-ieee-754-float-is-incapable-of-representing-e you're dealing with integers that do not have an exact representation in floating point. – wcochran Jul 23 '20 at 22:37
  • Related: https://stackoverflow.com/questions/588004/is-floating-point-math-broken – Code-Apprentice Jul 23 '20 at 22:58
  • @ThomasMatthews if y is a type with more precision than double (like `long long` or `long double`) then `pow(y, 2)` returns the truncated result. And even if the type fits in `double` then `pow(y, 2)` may also returns incorrect results because it may use some simple expressions like `exp(log(x) * y)`. See [Why does pow(n,2) return 24 when n=5, with my compiler and OS?](https://stackoverflow.com/q/25678481/995714), [Why pow(10,5) = 9,999 in C++](https://stackoverflow.com/q/9704195/995714), [Strange pow(x, y); behaviour](https://stackoverflow.com/q/14714115/995714) – phuclv Jul 24 '20 at 02:12

1 Answers1

0

pow() is function designed for floating point numbers(not for long long).

If your usage case consists of larger numbers, you might need to use some other library or make a custom function for that.

Raz Crimson
  • 187
  • 9