0

While sorting and displaying big numbers you usually end up displaying the large numbers in enotation. I was trying to display the whole number by using the <iomanip> library in cpp and it fails for very large numbers.

 //big sorting
    #include<bits/stdc++.h>
    #include<iomanip>
    using namespace std;
    int main()
    {
        int n;
        cin>>n;
        double arr[n];
        for (int i = 0;i < n; i++)
            cin>>arr[i];

        sort(arr, arr+n);
        cout<<fixed<<setprecision(0);
        for (int i = 0;i < n; i++)
            cout<<arr[i]<<endl; 
    }

Input:

31415926535897932384626433832795
1
3
10
3
5

Expected output:

1
3
3
5
10
31415926535897932384626433832795

Actual output:

1
3
3
5
10
31415926535897933290036940242944

The last digit is getting messed up.

double-beep
  • 5,031
  • 17
  • 33
  • 41

2 Answers2

1

The double type precision is only 15 decimal digits, so very large whole numbers can't be expressed in double type without loss of precison.

Alexander Pivovarov
  • 4,850
  • 1
  • 11
  • 34
  • could you also give me a solution like should I use long long int or something? – Krishnna Sarrdah Jun 02 '20 at 04:59
  • Well, there are multiple possible solutions depending on what is your intention. You need to set the requirement - i.e. answer questions like: (a) how large can your numbers be? (b) are the numbers necessarily whole numbers or can be others? (c) If all numbers are integers - can they be negative? – Alexander Pivovarov Jun 02 '20 at 05:03
  • I'm sorry I should've specified that in the question. – Krishnna Sarrdah Jun 02 '20 at 05:06
  • 2
    The particular number in your example `31415926535897932384626433832795` is larger than what 64 bit unsigned integer could fit, so `long long` won't be enough. It could fit in 128 bit integer though, but if you consider higher numbers it won't help. Not sure I read your notation correct - 2*10^5 means 20000? Or is it 2 to the power of 100000? If 20000 then why the number in your examples is much larger than that? – Alexander Pivovarov Jun 02 '20 at 05:10
  • n is just the size of the array – Krishnna Sarrdah Jun 02 '20 at 05:14
  • what about the numbers themselves? – Alexander Pivovarov Jun 02 '20 at 05:16
  • If you read the first sentence there carefully - you can see that they specify that each number is between 1 and 10^6 digits (so numbers can be ridiculously large). This is a very unusual thing in most programming tasks - so you probably want to specify it when asking anyone on how to handle such numbers (here or anywhere else). For this task there are many possible solutions, for example: (a) use Python which can handle arbitrary big integers, (b) represent numbers as strings of digits. – Alexander Pivovarov Jun 02 '20 at 05:27
  • 2
    @KrishnnaSarrdah *n is just the size of the array* -- First this, `double arr[n];` is not valid C++. Arrays in C++ must have their sizes known at compile time, not runtime. Use `std::vector arr(n);` instead. Second, if `n` was large, you risk exhausting the stack memory using `double arr[n]`. You shouldn't use the fake C++ in declaring arrays -- it is not valid C++ syntax, and can only cause more issues than you may think it solves. – PaulMcKenzie Jun 02 '20 at 05:40
  • @PaulMcKenzie - after you pointed out that thing I couldn't believe this compiles. Then I found this: https://stackoverflow.com/questions/737240/array-size-at-run-time-without-dynamic-allocation-is-allowed. This was very surprising to me. C++ holds a lot of secrets... – Alexander Pivovarov Jun 02 '20 at 06:05
1

Read more about C++, perhaps the C++11 standard n3337.

Read also the documentation of your C++ compiler, e.g. GCC (invoked as g++) or Clang (invoked as clang++). Read of course a good C++ programming book, since C++ is a very difficult programming language. Use C++ standard containers and smart pointers.

Large numbers does not fit natively in a computer memory (or in its registers). For example, with C++ code compiled by GCC on Linux/x86-64, an int has just 32 bits.

Consider using arbitrary precision arithmetic. You might be interested by GMPlib.

Floating point numbers are weird. Be sure to read the famous floating-point-gui.de website, and see also this answer.

#include<bits/stdc++.h>

is wrong since non-standard. Take the habit of #include-ing only headers needed by your translation unit, except if you use pre-compiled headers.

Take some time to read more about numbers and arithmetic. Some notion of modular arithmetic is incredibly useful when programming: a lot of computers are computing modulo 232 or 264.

Study for inspiration the C++ source code of existing open source software (e.g. on github or gitlab, including FLTK). If you use Linux, its fish-shell has a nice C++ code. You could even glance inside the source code of GCC and of Clang, both being nice C++ open source compilers.

In practice, read also about build automation tools such as GNU make (free software coded in C) or ninja (open source tool coded in C++).

Don't forget to use a version control system (I recommend git).

Read How to debug small programs.

Enable all warnings and debug info when compiling your C++ code (with GCC, use g++ -Wall -Wextra -g).

Read of course the documentation of your favorite debugger.

I am a happy user of GDB.

Consider using static program analysis tools such as the Clang static analyzer or Frama-C++.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • 1
    You might want to add `-pedantic` flag in the list of suggested compiler options. Without it the compiler won't catch the issue with declaring `double arr[n]` with `n` unknown at compile time. – Alexander Pivovarov Jun 02 '20 at 06:00