0

So, I am using sqrt function in c++ and the problem I am facing is, when the input to sqrt is 40000000001, it returns 200000.

#include <iostream>
#include <cmath>

using namespace std;

int main (void)
{
    long long int a;
    cin>>a;
    double b = sqrt(a);
    cout<<b<<"\n";
    return 0;
}

Why is this happening?

It should return 200000.0000025 and I need this exact value. Even getting 200000 produces a Wrong answer. Thanks!

Elliot
  • 483
  • 2
  • 6
  • 17
  • 5
    `std::cout << std::numeric_limits::max() << '\n';`. Something tells me you're going to get a value considerably lower than 40000000001. Something on the order of `2147483647` likely. – WhozCraig Jun 01 '15 at 07:06
  • ...and what is the size of your `int`? – Anders Lindahl Jun 01 '15 at 07:06
  • 2
    4-billion-and-1 is too big to fit in a 32-bit unsigned `int` (the most common size). Why don't you make `a` a `double` too? – Tony Delroy Jun 01 '15 at 07:06
  • possible duplicate of [Guaranteed precision of sqrt function in C/C++](http://stackoverflow.com/questions/22259537/guaranteed-precision-of-sqrt-function-in-c-c) – Hi-Angel Jun 01 '15 at 07:07
  • @TonyD that's not 4-billion, it's *40*-billion, but your point is still completely valid. – WhozCraig Jun 01 '15 at 07:09
  • 2
    The maxint issue would have been revelaed if you had used a debugger, or even printed out the int. – Martin James Jun 01 '15 at 07:09
  • Squaring 46341 gives 2147488281, a number suspiciously similar to that prophecised by @WhozCraig – Martin James Jun 01 '15 at 07:12
  • It's not result that is wrong, it is only the display of the result that cuts off the digits after the comma. You can check in a debugger or by adjusting the precision of the output. – Werner Henze Jun 01 '15 at 08:10

3 Answers3

4

adding a

cout << "a=" << a << endl;

will reveal that when you enter 40000000001 the value of a is actually 46341. This is because to represent 40000000001 in an int you'll need 36 bits, while on your platform, int most likely only has 32 bits (31 plus one sign).

Using a long instead, I get 200000 as a result. The fact that you don't get 200000.0000025 must have to do with the fact that also doubles only have a limited amount of precision. Even though Wikipedia says that a 64 bit double has a precision of typically 15-17 decimal digits and the number you are looking for has 13 significant digits, I suspect there are roundoff errors in the intermediate steps of the calculation.


Part of the problem is also the printing, if you print for example:

    cout << b - 200000 << endl;

then I get

    2.49999e-06

as output which is very close to 0.0000025 . You can increase the number of digits which are printed:

    cout << setprecision(13) << b << endl;

which then prints 200000.0000025 on my platform.


If you need more precision than the primitive types provide, there are libraries to do that, see e.g. this list on Wikipedia. In particular, boost seems to have a library for that and here is an example taking a square root of a 100 digit number: Square root of a 100 digit number in C++

Community
  • 1
  • 1
Andre Holzner
  • 18,333
  • 6
  • 54
  • 63
2

Use double instead of int , input value exceeded int max value .

#include <iostream>
#include <cmath> 
using namespace std;

int main()
{
    double a;
    cin >> a;
    double b = sqrt(a);
    cout << b << "\n";
}
Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
Venkata Naidu M
  • 351
  • 1
  • 6
1

You can use fixed, it make dipsplay unbrokenly.

   #include <iostream>
   #include <cmath>
   using namespace std;

    int main(void)
    {
        double a = 40000000001;
        cout << fixed << a << "\n";
        double b = (double )sqrt(a);
        cout << fixed <<b << "\n";
        return 0;
    }
zhangyiying
  • 414
  • 4
  • 15
  • I am not too sure if there is any such thing like long float. – Elliot Jun 01 '15 at 07:27
  • 1
    `long float` is not a standard type, I guess you mean `long double` (see http://en.wikipedia.org/wiki/C_data_types ) – Andre Holzner Jun 01 '15 at 07:28
  • @AndreHolzner, If the answer only for this question, double is OK – zhangyiying Jun 01 '15 at 07:30
  • A `double` can't store the exact result, but can store an approximation ( `200000.00000249998993240296840667724609375` for me), more digits of which can be seen with `#include ` and `setprecision(35)` or whatever value is desired. – Tony Delroy Jun 01 '15 at 07:47