Reputation: 27278
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
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
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
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
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
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
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
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
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
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
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
Reputation: 8805
if you don't need negative numbers, unsigned long long sounds like most you can get.
Upvotes: 1
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
Reputation: 19353
Doubles are floating-point. You should use long long, probably. I don't know which alias is the preferred one.
Upvotes: 0