4

I need to store 2^63 natural number in my program. Int has 4 bytes: http://www.cplusplus.com/doc/tutorial/variables/ so it is 2^(8*4) = 2^32, which type should I use?

Andrew Cottrell
  • 3,312
  • 3
  • 26
  • 41
Sławosz
  • 11,187
  • 15
  • 73
  • 106

9 Answers9

4

You can use unsigned long long, but I would check that your compiler supports that type.

#include <iostream>
int main()
{
    std::cout<<sizeof(unsigned long long)<< " bytes" << std::endl;
    return 0;
}

Prints 8 bytes on my machine which is enough room to store 2^63.

Jack Edmonds
  • 31,931
  • 18
  • 65
  • 77
3

This is architecture dependent. C++ doesn't have C's stdint.h header for guaranteed integer widths. On 64-bit linux long will be 64-bits.

I think C++11 adds cstdint as a wrapper for stdint.h. Then you can use int64_t.

Edit: As johannes pointed out, long is 32 bits in Windows. I'm not sure this can be done portably in C++03 while still maintaining full standards compliance. long long and int64_t are not a part of the C++03 standard, but are offered as compiler extensions by the common compilers.

Oscar Korz
  • 2,457
  • 1
  • 18
  • 18
  • 2
    long on win64 is 32-bits. On Unix/Linux it's 64-bit. One of the annoyances when writing portable code. As others mentioned long long, if supported is the way to go. (New in C++11) – johannes Oct 21 '11 at 18:39
  • you mean `long long`. On Windows, `long` is 32 bits in Windows. – Mooing Duck Oct 21 '11 at 18:41
  • Corrected. I should stop making assumptions about Windows, because it always seems to defy my expectations. – Oscar Korz Oct 21 '11 at 18:42
  • @OscarKorz, that's why limits.h exposes `LONG_MAX` and `ULONG_MAX`, so you can validate your assumptions. – MSN Oct 21 '11 at 18:45
1

On most modern processors, a long long int. Technically this is new to C99/C++11, but most C++ compilers have supported it since '99-ish.
Constants are the form 0LL

Mooing Duck
  • 64,318
  • 19
  • 100
  • 158
1

You can use the GNU multiple precision arithmetic library

It has a C++ Class Interface as well

Note:

C++ support in GMP can be enabled with --enable-cxx', in which case a C++ compiler will be required. As a convenience--enable-cxx=detect' can be used to enable C++ support only if a compiler can be found. The C++ support consists of a library libgmpxx.la and header file gmpxx.h (see Headers and Libraries).

Sujoy
  • 8,041
  • 3
  • 30
  • 36
0
#include <iostream>
using namespace std;

int main()
{
    unsigned long long result = 1;

    for(int i = 1; i <= 64; i++){
        if(i == 64){
            result = ((result * 2)-1);
        }
        else{
            result = ((result * 2));
        }


    }

    cout << "result is : " << result << endl;

    return 0;
}
naeem1098
  • 123
  • 2
  • 9
0

__int64 and long long are often used but not part of STL. long long for C will work with GCC if __int64 is not supported. in C99, if you need exactly 64 bits you can use int64_t,from <stdint.h>.

John Riselvato
  • 12,854
  • 5
  • 62
  • 89
0

Take a look at the *_MAX constants defined in limits.h for your compiler. If any of them are >= 2^63, use the type corresponding to that constant. For my compiler, ULLONG_MAX is 0xffffffffffffffffi64 or 18446744073709551615, which is >= 9223372036854775808 (2^63). So I would use unsigned long long as the type to hold natural numbers up to 2^63.

MSN
  • 53,214
  • 7
  • 75
  • 105
0

I don't know if this is helpful, but double is capable of representing the value pow(2, 63) exactly (no error). However, it can't represent pow(2, 63) + 1.0 exactly, nor can it represent pow(2, 63) - 1.0, so that might not be a helpful answer.

So if you actually want an integer representation of it, you need to use the unsigned 64-bit integer type (the signed type is not sufficient, as (1<<63) is a negative value). Unfortunately, 64-bit integer support is widespread but not entirely standardized. I believe that "unsigned long long int" works in all current-version compilers, but your mileage may vary. I deal with the variance by having a configuration header that typedef's a "uint64" and then typedefs it differently depending on the current compiler. Once C++11 is more widely implemented, it will add "unsigned int64_t", and that will be the correct way to do it after that point.

AHelps
  • 1,782
  • 11
  • 17
0

I'd recommend using a Big Integer library for this.

Here's a public domain one which works: https://mattmccutchen.net/bigint/

A T
  • 13,008
  • 21
  • 97
  • 158