tags:

views:

156

answers:

6

I'm using cout to print digits to the console. I am also storing values of up to 13+billion as a digit and doing computations on it. What data type should I use?

When I do the following:

int a = 6800000000;
cout << a;

It prints -1789934592.

thanks.

+6  A: 

Use int64_t to guarantee you won't overflow. It is available from stdint.h.

Matthew Flaschen
`int64_t` won't guarantee that generally! You can exceed its capacity, too.
Seth Johnson
"you" as in the OP who's storing up to ~13 billion. Obviously, `int64_t` can still overflow.
Matthew Flaschen
+9  A: 

long long can hold up to 9223372036854775807. Use something like gmp if you need larger.

Ignacio Vazquez-Abrams
+1 - `long long` is 8 bytes in GCC and VC++ regardless of the platform
Manuel
I'm not gonna downvote, but note that `long long` carries no guarantees in the standard. A C++ (0x, which formally adds it) compiler can make it 32-bit. If you have a definite bound, you're ALWAYS better off with the type that names the number of bits, `int64_t`.
Potatoswatter
@PotatoSwatter: Wrong - in both standards that define it (C99 and C++0x) it's 64 bits _minimum_. There would be no point in adding a 32 bits minimum type; we already have `long`. Furthermore, `int64_t` is pretty much by definition NOT FASTER than `long long`, as the latter type has less requirements (in particular, long long may be more than 64 bits)
MSalters
@MSalters: You are going to have to quote a section for an assertion like that. I agree that long long may be over 64 bits, but how does that make it "faster"? In that case, getting exactly 64 bits is still more desirable… and performance isn't the only consideration.
Potatoswatter
MSalters
@MSalters: I'm looking at §3.9.1 in N3000 and see nothing about specific requirements on the size of anything. Instead, it requires a typedef `int_least64_t` (§18.4.1). This seems totally incompatible with your assertion. Furthermore, fetching a 64-bit number will always be faster (amortized time) than fetching 128 bits, no matter what the ALU does.
Potatoswatter
+1  A: 

Your data type (int) is too small to hold such large numbers. You should use a larger data type or one of the fixed size data types as given in the other answer (though you should really use uint64_t if you're not using negative numbers).

Stephen Cross
A: 

You could use a long int:

long int a

Or if it's always going to be positive, an unsigned long int:

unsigned long int a

See: http://forums.guru3d.com/showthread.php?t=131678

akiller
Sorry but you're wrong.
Blindy
A: 

It's a good idea to understand the range limits of different sized types.

A 32 bit type (on most 32 bit platforms, both int and long are 32 bit) have the following ranges:

signed: -2,147,483,648 to 2,147,483,647
unsigned: 0 to 4,294,967,295

While 64 bit types (typically long long's are 64 bit, on most Unix 64 bit platforms a long is also 64) have the following range:

signed: -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
unsigned: 0 to 18,446,744,073,709,551,615
R Samuel Klatchko
I thought VC++'s long long was 64 bits also in 32 bit Windows?
Manuel
@Maneul - it is, let me clarify that.
R Samuel Klatchko
+2  A: 

Just a note that both int64_t and long long are included in C99 and in C++ 0x, but not in the current version of C++. As such, using either does put your code at some risk of being non-portable. Realistically, however, that risk is probably already pretty low -- to the point that when/if you port your code, there are likely to be much bigger problems.

If, however, you really want to assure against that possibility, you might consider using a double precision floating point. Contrary to popular belief, floating point types can represent integers exactly up to a certain limit -- that limit being set (in essence) by the size of the mantissa in the F.P. type. The typical implementation of a double has a 53-bit mantissa, so you can represent 53-bit integers with absolute precision. That supports numbers up to 9,007,199,254,740,992 (which is substantially more than 13 of either of the popular meanings of "billion").

Jerry Coffin
what is the datatype I would use for that 53-bit? double?
Shawn Mclean
@Shawn:yes. Of course, you do have to be careful -- for example, if you divide two of them, you'll get floating point division, not integer division...
Jerry Coffin
@Shawn: you will run into more portability problems by requiring an FPU than by requiring the ability to do 64-bit math.
Potatoswatter
@Potatoswatter:I can't imagine how you'd figure that. Most 32-bit CPUs include an FPU. Just for example, the last Intel x86 without an FPU was the 486sx, introduced around 1991 or so. By contrast, the first Intel x86s to support 64-bit integer math in hardware were some of the very last Pentium IV's, introduced around 2006 or so. Regardless of using an FPU per se, every C++ and C standard back to C89 has required a double with at least 10 digits of precision.
Jerry Coffin
Some CPU's don't have FPUs, for example embedded (which covers A LOT) and DSP. On the other hand, most CPUs of any kind support extended-precision arithmetic. You can often use `uint64_t` on a 16-bit processor. It just requires 4 chained extended-precision addition instructions — far faster than software FP.
Potatoswatter
@Potatoswatter:While it's certainly true that hardware varies, we're left with one simple fact: every conforming implementation of C++ *must* include double, and double *must* support at least 10 digits of precision. By contrast, *no* C++ compiler is required to support a 64-bit integer type. Even in C++ 0x, int64_t will be *optional*, not required. If you write code for a Microchip PIC (for example) it may lack an FPU -- but it probably won't support int64_t either. *Some* sort of support for a conforming double is much more widespread than support of int64_t.
Jerry Coffin
Potatoswatter
@Potatoswatter: Not even close to true. Just for a few obvious examples, all the 486DX, Pentium, Pentium Pro, Pentium II, Pentium III and most Pentium IV machines had FPUs, but no direct 64-bit support. Likewise, virtually all PowerPC based Macs. Likewise about a bajillion ARM processors, such as in your average mobile phone. Likewise a zillion SPARCs, SuperSPARCs, MicroSPARCs. Likewise, anything with a 68020, 68030, 68040, etc. I won't bore you with more, but you get the idea...
Jerry Coffin
@Jerry: 64-bit support does not require 64-bit hardware. I've used `int64_t` on the 68000, long ago. We can pretty much ignore both 64-bit registers and FPUs for the purposes of this argument.
Potatoswatter
Also, see what the standard actually says about `double`: "The value representation of floating-point types is implementation-defined." (§3.9.1/8) There must be some type called `double`, but it is only what you expect if `numeric_limits<double>::is_iec559 == true`.
Potatoswatter
The `double` implementation doesn't matter. `double` must have at least 12 significant digits, independent of the precise representation. 13 billion takes only 11 digits.
MSalters