4

In my assignment, it says "Do not add long int or long long private members to accomplish this as there is no guarantee that either can actually store larger numbers than an int." I know that int has a maximum of 2^31-1 and long long has a maximum of 2^63-1. So can someone give me an example to me why the given sentence is true?

Thanks in advance!

user44322
  • 351
  • 3
  • 8

2 Answers2

7

It means exactly what it says. There's no guarantee that a long long can store more numbers than an int. It's at least as big, but it can be the same.

I know that int has a maximum of 2^31-1 and long long has a maximum of 2^63-1

This can be true for some platform, with some compiler, but it's not always the same. C++ doesn't guarantee either.

3.9.1 Fundamental types [basic.fundamental]

2) 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. [...] (emphasis mine)

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • But I thought long long can store any value in the range of –9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 – user44322 Nov 19 '12 at 02:37
  • @user44322 what's your reference for that? – Luchian Grigore Nov 19 '12 at 02:37
  • I think in C++11, `long long` is guaranteed to be bigger or something. – chris Nov 19 '12 at 02:41
  • 1
    @chris "at least" - added the reference. – Luchian Grigore Nov 19 '12 at 02:41
  • @user44322 the standard reference preceds the one from MS. See the edit. – Luchian Grigore Nov 19 '12 at 02:42
  • So you guys are saying that if I use long long, there is a chance that my teacher is using a compiler that doesn't support long long to its actual value. – user44322 Nov 19 '12 at 02:45
  • @LuchianGrigore, Yup, I looked through myself and found nothing. I swear I heard it had to be bigger somewhere, though :/ – chris Nov 19 '12 at 02:45
  • @user44322 no. We're saying that what you mean by "actual value" isn't correct. A correct actual value follows the specs in the standard. It's correct for `sizeof(int)` to be equal to `sizeof(long long int)`. – Luchian Grigore Nov 19 '12 at 02:45
  • I meant, if I put a value into long long like 2^63-1, it might give an overflow on the submission server even if it doesn't overflow on my computer. – user44322 Nov 19 '12 at 02:48
  • To clarify: `char` must be at least 8 bits. `short` and `int` must be at least 16 bits. `long int` must be at least 32 bits. `long long int` must be at least 64 bits. You could probably create a conforming implementation in which they were all 64 bits (though C-style I/O assumes `int` is larger than `char`). But no -- 2^63-1 will *not* overflow a long long int on any machine (at least with a conforming implementation -- and I've never heard even a suggestion of an implementation that didn't conform in this respect). – Jerry Coffin Nov 19 '12 at 02:50
  • Well, if I use the types defined in cstdint as suggested by Reuben Morais then it will guarantee to be able to contain 2^63-1? – user44322 Nov 19 '12 at 02:52
  • If you use `long long` or `int64_t` (presuming it exists) you're guaranteed that either will hold 2^63-1. – Jerry Coffin Nov 19 '12 at 02:53
  • But according to Luchian Grigore, there is no guarantee that 2^63-1 can be stored in long long. – user44322 Nov 19 '12 at 02:55
  • @user44322, if you're in doubt check out the values in `` `std::numeric_limits`. – Mark Ransom Nov 19 '12 at 02:55
  • @user44322: In this care, Luchian is wrong. It's a rare occasion -- probably want to write it on the calendar or something! – Jerry Coffin Nov 19 '12 at 02:57
  • @JerryCoffin I don't see how or where it's guaranteed that a long long int can store 2^63-1. I agree about `int64_t`. – Luchian Grigore Nov 19 '12 at 02:58
  • The C++ standard refers to the C standard. Annex E of the C standard specifies the minimum magnitudes for long long as:: `#define LLONG_MAX +9223372036854775807` and `#define LLONG_MIN -9223372036854775807`. (technically Annex E is "informative" -- the same information is also somewhere normative though -- I'm just too lazy to find it at the moment). – Jerry Coffin Nov 19 '12 at 03:01
  • @JerryCoffin where is this referral? – Luchian Grigore Nov 19 '12 at 03:03
  • §18.3.3/1, among other places. – Jerry Coffin Nov 19 '12 at 03:07
  • @JerryCoffin /2 - "The types of the constants defined by macros in are not required to match the types to which the macros refer." – Luchian Grigore Nov 19 '12 at 03:10
  • @LuchianGrigore: Yes -- that doesn't mean the values may be wrong. It means that (for example) they're free to specify SHRT_MIN as `-32768`, even though `-32768` isn't a `short` (the literal doesn't include the `-`, so the literal itself is `32768`, which won't fit in a 16-bit short, so it'll be `int` if that's 32 bits, or `long` if `int` is only 16 bits). – Jerry Coffin Nov 19 '12 at 03:18
2

The C standard specifies two relevant criteria:

  • sizeof(char) ≤ sizeof(short) ≤ sizeof(int) ≤ sizeof(long) ≤ sizeof(long long) ≤ sizeof(uintmax_t)

    This is specified indirectly in ISU/IEC 9899:2011, §6.2.5 Types, ¶8: For any two integer types with the same signedness and different integer conversion rank (see 6.3.1.1), the range of values of the type with smaller integer conversion rank is a subrange of the values of the other type.

  • The minimum permitted value for the maxima of the types (ISO/IEC 9899:2011, §5.2.4.2.1 Sizes of integer types <limits.h>):

    • SCHAR_MAX ≥ 127 // 27-1
    • SHRT_MAX ≥ 32,767 // 215-1
    • INT_MAX ≥ 32,767 // 215-1
    • LONG_MAX ≥ 2,147,483,647 // 231-1
    • LLONG_MAX ≥ 9,223,372,036,854,775,807 // 263-1

The quote is formally correct; it is possible to devise systems where long does not store a larger range than int — indeed, this is the case on most 32-bit systems (all the ones I know of), and also true on Windows 64. It is less likely to be accurate w.r.t long long; I know of no system where sizeof(int) == sizeof(long long) (and, because of the inequality quoted, sizeof(int) == sizeof(long)). On most Unix 64-bit systems, sizeof(int) == 4, sizeof(long) == 8, and sizeof(long long) == 8; on Windows 64, sizeof(long) == 4 and only long long (or __int64) is a 64-bit type.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278