Large numbers - which type should I choose ?

Hi there,

I've a question regarding large numbers. My program needs to read max 10^20-digit number and I'm wondering which type is best for this.

I tried to use float or double, but it didn't work. When I used long double, the whole number was finally read. But at this page:

http://www.cplusplus.com/doc/tutorial/variables/

we can read that double has the same range as long double. So I'm afraid that despite that the code works on my computer, it may fail on the other...

So what would you recommend for me in this situation ?

PS. I can only use built-in types and standard library...

Thx for help in advance ;)
So what would you recommend for me in this situation ?

PS. I can only use built-in types and standard library...


I'd recommend using one of the many high-quality bignum libraries. If you really are forbidden to do that, and the primitive types aren't enough for you, you're going to have to create a new class yourself, and the mathematical operators to go with it that you need.

Do you really mean 10^20 digit number? That's

1 00 000 000 000 000 000 000 digits.


Did you mean 10 to 20 digits? :)

Last edited on
you could make a bignum class yourself if you can only use primitives...
LOL, sorry. I meant 20-digit number :P

Hmm, I can use long long since every compiler knows this type, but i'd like to use sqrt function on it. And as we know, it hasn't got argument of long long type...
Actually, that's not true. long long is gnu-specific and is not specified as part of the current
C++ standard.

If you need to be able to use sqrt() or need to take the square root of a number, you
have two choices: either use a floating point type or invent your own type, but then you
have to write your own version of sqrt(). The latter is pretty non-trivial.

The problem is that a double, being 8 bytes, while giving you a range of well beyond 20
digits, only gives you about 14-15 digits of accuracy, even when the number you are
holding is integral.

unsigned long long is gnu-specific and has an upper range of about 1.8 * 10^19 which
doesn't quite suffice your need either.
Heres a comparison of size from my compiler (MinGW custom Distro :: CodeBlocks 10.06):
               Max Char:                   127 via 1 bytes
              Max Short:                 32767 via 2 bytes
                Max Int:            2147483647 via 4 bytes
           Max unsigned:            4294967295 via 4 bytes
               Max long:            2147483647 via 4 bytes
              Max float:          3.40282e+038 via 4 bytes
             Max double:          1.79769e+308 via 8 bytes
        Max long double:         1.18973e+4932 via 12 bytes
          Max long long:   9223372036854775807 via 8 bytes
 Max unsigned long long:  18446744073709551615 via 8 bytes

Process returned 0 (0x0)   execution time : 0.015 s
Press any key to continue.


Ugly long source code (Could have use templates I'm sure.)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <limits>
#include <iomanip>
#include <iostream>

int main()
{
  std::cout << std::setw(25) << "Max Char: " << std::setw(21) << (int) std::numeric_limits< char >::max() << " via " << sizeof(char)<< " bytes" << std::endl;
  std::cout << std::setw(25) << "Max Short: " << std::setw(21) << std::numeric_limits< short >::max() << " via " << sizeof(short)<< " bytes" << std::endl;
  std::cout << std::setw(25) << "Max Int: " << std::setw(21) << std::numeric_limits< int >::max() << " via " << sizeof(int)<< " bytes" << std::endl;
  std::cout << std::setw(25) << "Max unsigned: " << std::setw(21) << std::numeric_limits< unsigned >::max() << " via " << sizeof(unsigned)<< " bytes" << std::endl;
  std::cout << std::setw(25) << "Max long: " << std::setw(21) << std::numeric_limits< long >::max() << " via " << sizeof(long)<< " bytes" << std::endl;
  std::cout << std::setw(25) << "Max float: " << std::setw(21) << std::numeric_limits< float >::max() << " via " << sizeof(float)<< " bytes" << std::endl;
  std::cout << std::setw(25) << "Max double: " << std::setw(21) << std::numeric_limits< double >::max() << " via " << sizeof(double)<< " bytes" << std::endl;
  std::cout << std::setw(25) << "Max long double: " << std::setw(21) << std::numeric_limits< long double >::max() << " via " << sizeof(long double)<< " bytes" << std::endl;
  std::cout << std::setw(25) << "Max long long: " << std::setw(21) << std::numeric_limits< long long >::max() << " via " << sizeof(long long)<< " bytes" << std::endl;
  std::cout << std::setw(25) << "Max unsigned long long: " << std::setw(21) << std::numeric_limits< unsigned long long >::max() << " via " << sizeof(unsigned long long)<< " bytes" << std::endl;

  return 0;
}

Unsigned long long sounds fine then :) I'll use it, and write my own sqrt function.
Topic archived. No new replies allowed.