Igor
Igor

Reputation: 27278

What type to use for integers larger than 2^32 in C++?

I have an integer variable, that can get a value larger than 4294967295.

What type should I use for it (long long, or double, or something else)?

Upvotes: 13

Views: 40258

Answers (14)

user9876
user9876

Reputation: 11102

I'm going to assume your numbers will fit in 64 bits. If not, then you need an arbitrary-precision arithmetic library such as GMP.

In theory, there's no easy, portable way to do 64-bit maths in C++. In practise, most C++ compilers also support the "old fashioned" C headers, and C99 has a nice header called stdint.h.

So first do:

#include <stdint.h>

Then use types int64_t (signed) and uint64_t (unsigned).

EDIT TO ADD: After I wrote this answer, C++11 added the <cstdint> header which normally* defines std::int64_t and std::uint64_t , so if you have a modern compiler it's best to use those.

(* In theory the system might not support a 64-bit type at all. But in practise it will, on any system you're likely to come across).

Upvotes: 9

Sbspider
Sbspider

Reputation: 399

Just out of curiosity - I don't think it would be too hard to code your own if you wanted to. I mean, all of these data types have predefined structures, of course, but you could, for example, use the double structure which uses exponents, and do something like this:

to hold a VERY large number, beyond the scale of a double, create an object that has two parts to it - the number and the power to ten,

so, if you wanted to store something like

1.1230123123 x 10^(100000000000000000000000000000000000), which isn't supported by a double, you could have the 1.123 ... part stored in a double, and then the power of ten as a seperate double/int/float (whatever suits), and then take it from there. Of course, this may not be the best way - and you would probably have to code in a lot of functionality for division, subtraction etc, but it would definitely by portable, as you would be using the normal data types defined. The useability of this would depend on what you are trying to achieve and whether or not you plan to use this beyond a single project, but I think it is a liable way to do it if those sorts of numbers are an absolute requirement

Upvotes: 0

TrayMan
TrayMan

Reputation: 7445

How portable should your program be? TR1 has cstdint and stdint.h so it's likely supported by most up-to-date compilers. Then there is Boost cstdint.hpp that you should be able to use if cstdint is not supported.

Upvotes: 1

lispmachine
lispmachine

Reputation: 4526

A lot of current C/C++ compilers have either stdint.h or inttypes.h header.

int_fast64_t or int64_t may be an option (IMHO the most portable).

Upvotes: 1

anon
anon

Reputation:

Don't use double, because:

cout.setf(ios::fixed);
cout << LONG_LONG_MAX << endl;
cout << double(LONG_LONG_MAX) << endl;

cout << LONG_LONG_MAX-100 << endl;
cout << double(LONG_LONG_MAX-100) << endl;

Output:

9223372036854775807
9223372036854775808.000000
9223372036854775707
9223372036854775808.000000

Upvotes: 3

PowerApp101
PowerApp101

Reputation: 1826

Try TTMath. All you need to do is include a single header and then declare a bignum type such as:

typedef ttmath::UInt<100> BigInt;

which creates a type that can hold unsigned integers between 0 and 2 ^ (32*100)-1. Then just use BigInt wherever you would use int.

Of course you can choose whatever size you like for the template parameter. 100 might be overkill ;-)

Just realised, the lib only works on x86 and x64, but is OS cross-platform on those processors.

Upvotes: 1

Igor
Igor

Reputation: 27278

Both proposals aren't good because long long is not a standard C++ data type, and double is a floating-point.

Since my program has to be portable, I am going to #define my own types, that suit all the compilers that I use (visual studio and gcc) :

#ifdef WIN32
  #define unsigned_long_long unsigned __int64
  #define long_long __int64
#else // gcc. Might not work on other compilers!
  #define unsigned_long_long unsigned long long
  #define long_long long long
#endif

Upvotes: 3

David Allan Finch
David Allan Finch

Reputation: 1424

If your compiler does not have long long you can implement them yourself with a structure containing two long but you will need to be caurseful with carry etc. You could of course look for a Multiple Precision Arithmetic like GMP

Upvotes: 0

user75832
user75832

Reputation:

I use

uint64_t

But it's not standard.

Upvotes: 2

Pod
Pod

Reputation: 4129

Try:

http://gmplib.org/ big num.

http://mattmccutchen.net/bigint/ big int.

I've used neither, but I've used similiar things in Java.

Upvotes: 13

anon
anon

Reputation:

There is no portable way of doing this in C++, as the language does not specify the size of integer types (except sizeof char is 1). You need to consult your compiler documentation.

Upvotes: 7

Slartibartfast
Slartibartfast

Reputation: 8805

if you don't need negative numbers, unsigned long long sounds like most you can get.

Upvotes: 1

sharptooth
sharptooth

Reputation: 170569

Use long long and if possible add a compile-time assertion that this type is wide enough (smth like sizeof( long long ) >= 8).

double is for floating-point, not integer.

Upvotes: 14

alamar
alamar

Reputation: 19353

Doubles are floating-point. You should use long long, probably. I don't know which alias is the preferred one.

Upvotes: 0

Related Questions