tags:

views:

1311

answers:

13

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)?

A: 

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

alamar
+10  A: 

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.

sharptooth
long long is not a standard C++ data type
anon
According to ISO/IEC 9899:TC3 - Committee Draft — Septermber 7, 2007 - Major changes from the previous edition include: the long long int type and library functionsmaximum value for an object of type long long intLLONG_MAX 9223372036854775807 (2^63 - 1)
That is a C99 document, not C++.
anon
@Neil: +1I always thought it was the same in C++, but it seems it is not. According to Working Draft, Standard for Programming Language C++ (N2798=08-0308): There are five standard signed integer types : “signed char”, “short int”, “int”, “long int”, and “long long int”. In this list, each type provides at least as much storage as those preceding it in the list.
Note the N2798 document you quote from is the unratified C++0x draft - standard C++ does not yest have long long integers.
anon
long long works with g++, so if you happen to use that it's OK and it will be supported in C++0x, too.
lothar
long long also works in MSVC, just for the record
DrJokepu
A: 

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

Slartibartfast
+9  A: 

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.

anon
Not quite true. The standard does specify the minimum magnitudes of each type and thus by implication a minimum bit (not byte) count see http://stackoverflow.com/questions/271076/what-is-the-difference-between-an-int-and-a-long-in-c/271132#271132
Martin York
+9  A: 

Try:

http://gmplib.org/ big num.

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

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

Pod
gmplib is great +1
dfa
+2  A: 

I use

uint64_t

But it's not standard.

Ben Reeves
Actually stdint.h is part of C99. But many compiler vendors are relucent in supporting "new" standard even after 10 years (anyone remembers how IT looked like 10 years ago?!).
lispmachine
I don't know about your work, but for me, only three compiler vendors matter. Microsoft, Intel, and GCC. And all three have traditionally been good at "new" standard compliance. Not so much SunW C++ or HP or IBM, but in the Windows/Linux world, it should be a non-issue.15 years ago, I remember breaking compilers and linkers for breakfast. In fact, it took DEC the better part of two months to fix a linker bug so we could ship Pro/ENGINEER for WindowsNT Alpha, back in the days when 32 MB executables where unheard of.
Chris Kaminski
A: 

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

David Allan Finch
+3  A: 

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
Igor Oks
Note this is not a Windows issue, it is a C++ standards issue - there is no guaranteed that non-windows platforms will support long long.
anon
According to MSDN long long is equivalent to __int64 in VC++ and so you don't need that define.
sharptooth
Also note that g++ will emit lots of warnings if compiled with -pedantic, which I think most C++ programs are (they certainly should be)
anon
Neil: Why would it emit warnings?
Igor Oks
Because long long is not standard C++ - it is part of C99, which g++ supports. Using -pedantic to compile C++ code will give aq warning about this.
anon
If you really want to go that way, you would be better off using a portable library (ACE comes to mind) that provides 64 bit integers (ACE_INT64, ACE_UINT64) across platforms and operating systems. It is non-standard (detects the platform/compiler and uses your own type of hacks) but will work on other systems.
David Rodríguez - dribeas
A: 

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.

20th Century Boy
+3  A: 

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
Yes, double will some of the bits to identify the exponent, actually loosing precision (as compared to an integer type of the same size)
David Rodríguez - dribeas
+1  A: 

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).

lispmachine
+5  A: 

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:

#incude <stdint.h>

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

user9876
+1  A: 

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.

TrayMan