45

I'm confused with range of values of Int variable in C.

I know that a 32bits unsigned int have a range of: 0 to 65,535. So long has 0 to 4,294,967,295

This is fine in 32bits machine. But now in 64bits machines all thing keep the same? Or maybe my int capacity is different?

I understand this questions as newbie, but I'm really confused. This method signature is not helping too. :)

unsigned long long int atomicAdd(unsigned long long int* address, unsigned long long int val);
Custodio
  • 8,594
  • 15
  • 80
  • 115
  • 8
    32-bit unsigned integers have a max value of 2^32 - 1, which is way more than 65535 (2^16 - 1). – Will A May 27 '11 at 17:37

10 Answers10

70

In C and C++ you have these least requirements (i.e actual implementations can have larger magnitudes)

signed char: -2^07+1 to +2^07-1
short:       -2^15+1 to +2^15-1
int:         -2^15+1 to +2^15-1
long:        -2^31+1 to +2^31-1
long long:   -2^63+1 to +2^63-1

Now, on particular implementations, you have a variety of bit ranges. The wikipedia article describes this nicely.

Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
  • 1
    Nice, can you say that is the `long long int` definition in method signature of question? – Custodio May 27 '11 at 17:49
  • 3
    @Custodio you used `unsigned long long`, which means you have a range of at least `0 .. 2^64-1`. – Johannes Schaub - litb May 27 '11 at 17:52
  • Nice, this signature is from a framework that I'm using, And I'm having problem calling the AtomicAdd – Custodio May 27 '11 at 18:16
  • 3
    Sorry for commenting after a long time, but I have a feeling that C follows 2's complement arithmetic, where values lie in [-2^(N-1), 2^(N-1)-1] for N-bit data type. Can you please verify this (No extra 1 in lower endpoint)? – mg007 Jul 08 '13 at 18:55
  • How about `long double` (`double`)? – kenorb Aug 19 '14 at 10:21
  • The ranges are clearly wrong. long: -2^31 to +2^31-1 – sumanth232 May 24 '15 at 19:34
  • 1
    @krishna222 it is not wrong. the limits are drafted such that not only 2's complement can be used, but also one's complement and sign magnitude. therefore the least lower limit is `-2^31+1` rather than `-2^31` (which would end up as -0 for sign magnitude on 32 bits..). – Johannes Schaub - litb May 24 '15 at 20:11
  • @JohannesSchaub-litb, but C , C++ follows 2 compliement, right ? int x = 0x80000000; printf("x = %d", x); -> prints x = -2147483648 which is equal to -2^31 – sumanth232 May 26 '15 at 06:28
20

No, int in C is not defined to be 32 bits. int and long are not defined to be any specific size at all. The only thing the language guarantees is that sizeof(char)<=sizeof(short)<=sizeof(long).

Theoretically a compiler could make short, char, and long all the same number of bits. I know of some that actually did that for all those types save char.

This is why C now defines types like uint16_t and uint32_t. If you need a specific size, you are supposed to use one of those.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
T.E.D.
  • 44,016
  • 10
  • 73
  • 134
  • 5
    That's why I get `sizeof(int)`=4 and `sizeof(long)`=4 on my Linux system (GCC). Since, there's no specific size but a _min size_ instead. – CᴴᴀZ Aug 23 '14 at 08:11
  • It also guarantees some *minimum* sizes. – Martin Bonner supports Monica Dec 18 '15 at 10:42
  • Umm, isn't it a C requirement that sizeof(char) = 1? And since there must be an `int8_t` type, does that not mean it is also effectively a requirement that `CHAR_BITS == 8`? Also, AFAICR Posix requires `CHAR_BIT == 8` anyway. Meaning that it is **not** OK for a compiler to make `char` and `short` the same type. Although I guess `short` = `int` = `long` is OK. – einpoklum Mar 23 '16 at 20:11
  • @einpoklum - According to what I can dig up, CHAR_BITS [must be *at least* 8](https://en.wikipedia.org/wiki/C_data_types#Interface_to_the_properties_of_the_basic_types), but may be more. But that's today, if your compiler happens to be conformant to that particular standard. Back in '11 when I wrote this, I still occasionally had to work on systems with K&R'ish compilers. In a world chock full of non-standard compilers, quoting today's standard isn't the end of the discussion. – T.E.D. Mar 23 '16 at 20:55
  • But it's not "perfectly OK", it's against the C99 standard, which is almost 20 years old already. So - would suggest an edit. – einpoklum Mar 23 '16 at 22:14
  • 1
    @einpoklum - I'll rephrase that, since the "OK" seems to bug people so much. But I think lots of people think things are "standard" that are not. There's a **reason** they made those sized types (including int8_t and uint8_t). I'm pretty sure they can indeed legit all be the same size. – T.E.D. Mar 23 '16 at 23:20
  • @einpoklum ...note that the inequality relation in my answer, including the part about char, can be found nearly verbatim in this OpenGroup [whitepaper about C data sizes](http://www.unix.org/whitepapers/64bit.html) on 64-bit systems. – T.E.D. Mar 23 '16 at 23:31
  • There are also guarantees that certain ranges of values can be represented in each type; see the top-voted answer – M.M Jan 31 '17 at 05:40
  • @einpoklum `int8_t` is not guaranteed to exist in ISO C. The intNN_t types are all *optional* and if the implementation cannot satisfy the requirements then it will not offer those types. – M.M Jan 31 '17 at 05:41
  • @chux - I suppose that might be a useful clarification on platforms where unsigned and signed types are different sizes. Are there any such platforms? – T.E.D. Jan 11 '18 at 22:20
  • @T.E.D. I apologize - I mis-thought as `sizeof(char)<=sizeof(short)` meaning `CHAR_MAX <= SHRT_MAX`, which might not be true where as `UCHAR_MAX <= SHRT_MAX` is certainly true. – chux - Reinstate Monica Jan 12 '18 at 02:24
19

Excerpt from K&R:

short is often 16 bits, long 32 bits and int either 16 bits or 32 bits. Each compiler is free to choose appropriate sizes for its own hardware, subject only to the restriction that shorts and ints are at least 16 bits, longs are at least 32 bits, and short is no longer than int, which is no longer than long.


You can make use of limits.h that contains the definition of the limits for the decimal/float types:

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <float.h>


int main(int argc, char** argv) {

    printf("CHAR_BIT    :   %d\n", CHAR_BIT);
    printf("CHAR_MAX    :   %d\n", CHAR_MAX);
    printf("CHAR_MIN    :   %d\n", CHAR_MIN);
    printf("INT_MAX     :   %d\n", INT_MAX);
    printf("INT_MIN     :   %d\n", INT_MIN);
    printf("LONG_MAX    :   %ld\n", (long) LONG_MAX);
    printf("LONG_MIN    :   %ld\n", (long) LONG_MIN);
    printf("SCHAR_MAX   :   %d\n", SCHAR_MAX);
    printf("SCHAR_MIN   :   %d\n", SCHAR_MIN);
    printf("SHRT_MAX    :   %d\n", SHRT_MAX);
    printf("SHRT_MIN    :   %d\n", SHRT_MIN);
    printf("UCHAR_MAX   :   %d\n", UCHAR_MAX);
    printf("UINT_MAX    :   %u\n", (unsigned int) UINT_MAX);
    printf("ULONG_MAX   :   %lu\n", (unsigned long) ULONG_MAX);
    printf("USHRT_MAX   :   %d\n", (unsigned short) USHRT_MAX);
    printf("FLT_MAX     :   %g\n", (float) FLT_MAX);
    printf("FLT_MIN     :   %g\n", (float) FLT_MIN);
    printf("-FLT_MAX    :   %g\n", (float) -FLT_MAX);
    printf("-FLT_MIN    :   %g\n", (float) -FLT_MIN);
    printf("DBL_MAX     :   %g\n", (double) DBL_MAX);
    printf("DBL_MIN     :   %g\n", (double) DBL_MIN);
    printf("-DBL_MAX     :  %g\n", (double) -DBL_MAX);

    return (EXIT_SUCCESS);
}

Maybe you might have to tweak a little bit on your machine, but it is a good template to start to get an idea of the (implementation-defined) min and max values.

Ely
  • 10,860
  • 4
  • 43
  • 64
9

There's no one answer. The standard defines minimum ranges. An int must be able to hold at least 65535. Most modern compilers however allow ints to be 32-bit values. Additionally, there's nothing preventing multiple types from having the same capacity (e.g. int and long).

That being said, the standard does say in your particular case:

0 → +18446744073709551615

as the range for unsigned long long int.

Further reading: http://en.wikipedia.org/wiki/C_variable_types_and_declarations#Size

Joe
  • 41,484
  • 20
  • 104
  • 125
  • An `int` must be able to hold at least 32767. It might not be able to hold 65535. On typical 16-bit implementations it wouldn't. – M.M Jan 31 '17 at 05:50
2

In C and C++ memory requirements of some variable :

signed char: -2^07 to +2^07-1
short: -2^15 to +2^15-1
int: -2^15 to +2^15-1
long: -2^31 to +2^31-1
long long: -2^63 to +2^63-1

signed char: -2^07 to +2^07-1
short: -2^15 to +2^15-1
int: -2^31 to +2^31-1
long: -2^31 to +2^31-1
long long: -2^63 to +2^63-1

depends on compiler and architecture of hardware

The international standard for the C language requires only that the size of short variables should be less than or equal to the size of type int, which in turn should be less than or equal to the size of type long.

Vipin Diwakar
  • 115
  • 1
  • 3
  • 4
    These values are wrong. The values given in Johannes Schaub's answer, which you have attempted to correct, are the actual values given by the standard as the minimum required to be supported by an implementation. – interjay Jul 11 '13 at 08:49
  • Specifically, signed char is NOT required to support -2^7 (-128). It only has to cope with -127. Two's complement machines will support -128, but sign-and-magnitude will only go down to -127 (which is exactly why the limit is what it is). Similarly for the other types – Martin Bonner supports Monica Dec 18 '15 at 10:41
2

In fact, unsigned int on most modern processors (ARM, Intel/AMD, Alpha, SPARC, Itanium ,PowerPC) will have a range of 0 to 2^32 - 1 which is 4,294,967,295 = 0xffffffff because int (both signed and unsigned) will be 32 bits long and the largest one is as stated.

(unsigned short will have maximal value 2^16 - 1 = 65,535 )

(unsigned) long long int will have a length of 64 bits (long int will be enough under most 64 bit Linuxes, etc, but the standard promises 64 bits for long long int). Hence these have the range 0 to 2^64 - 1 = 18446744073709551615

Henno Brandsma
  • 2,116
  • 11
  • 12
1

Take a look at limits.h. You can find the specific values for your compiler. INT_MIN and INT_MAX will be of interest.

Paul Rubel
  • 26,632
  • 7
  • 60
  • 80
1

Have a look at the limits.h file in your system it will tell the system specific limits. Or check man limits.h and go to the "Numerical Limits" section.

phoxis
  • 60,131
  • 14
  • 81
  • 117
0

A 32-bit unsigned int has a range from 0 to 4,294,967,295. 0 to 65535 would be a 16-bit unsigned.

An unsigned long long (and, on a 64-bit implementation, possibly also ulong and possibly uint as well) have a range (at least) from 0 to 18,446,744,073,709,551,615 (264-1). In theory it could be greater than that, but at least for now that's rare to nonexistent.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
-5

It is better to include stdlib.h. Since without stdlibg it takes long as long

Sanoj Kashyap
  • 5,020
  • 4
  • 49
  • 75