1

What is meant by the size of a type will determine how many different possible values a variable can hold

For example in my book, it says that a char variable can hold a range of values from -128 to 127

I am just trying to understand what the text in bold implies.

  • It implies exactly what you quoted. It gets clearer if you compare the range covered by a 16bit (2 bytes) wide variable. `256 * 256`, some 64k, or -32k to + 32k-1 – Yunnosch Sep 13 '21 at 11:46
  • 2
    The size of the type determines how many bits it contains. If the `char` is 8 bits (it isn't always) it can hold 2^8 = 256 different values. Whether these represent 0..255 or -128..127 depends on whether the type is `unsigned` or `signed`. – Weather Vane Sep 13 '21 at 11:47
  • Does this answer your question? [What does "-1" represent in the value range for unsigned int and signed int?](https://stackoverflow.com/questions/57703450/what-does-1-represent-in-the-value-range-for-unsigned-int-and-signed-int) – Yunnosch Sep 13 '21 at 11:50
  • I proposed a duplicate. The question is not the same, but the answers there (admittedly one by me) should tell you all you want/need to know to understand your questions answers as hinted in the comments beneath it. – Yunnosch Sep 13 '21 at 11:51
  • 1
    The size of a variable is the number of bits of memory it takes, that limit the range of numbers that can be stored. For example in a 1bit variable you can store 2 values, in a byte you can store 2^8 = 256 numbers (0..255 or -128..+127). – Davide Madrisan Sep 13 '21 at 11:52
  • can you put more context? what type, what variable? – tstanisl Sep 13 '21 at 12:01
  • @tstanisl It is actually a generalisation that is always valid, regardless of type. – Cheatah Sep 13 '21 at 12:16
  • @Cheatah, but every type has its size, so this sentence sounds like "a type will determine how many different possible values a variable can hold" what not very enlightening. Usually `sizeof(bool) == sizeof(unit8_t)`. But bool can handle just 2 values, while `uint8_t` can handle 256 – tstanisl Sep 13 '21 at 12:19
  • 2
    The book is wrong. The size of a type, that is, the number of bits in it, will determine an upper bound on how many values a variable of that type can hold. n bits have 2^n different settings, so a type with n bits can represent **at most** 2^n values. However, the values a type represents are determined by the semantics of that type. Some combinations of bits may represent the same values as other combinations (e.g., decimal floating point bits for 1.234•10^3 and 12.34•10^2) or may not represent valid values at all (e.g., 32-bit pointer types when the address space is only 24 bits). – Eric Postpischil Sep 13 '21 at 12:21
  • That is a fair clarification, I admit. Similarly I could see an `enum` being limited even if it's internally treated like an `int`. – Cheatah Sep 13 '21 at 12:24
  • @EricPostpischil, it's even more complex. Two pointer can have the same representation while not being equal, thus have *different* values. This in theory, this could let the variable have *more* values than indicated by `sizeof`. At least in abstract C machine. – tstanisl Sep 13 '21 at 12:24
  • @Qurlarmahmoses Read it in the same way you would "The size of a number will determine the number of different values it can hold." A 3-digit number can hold values from 1 to 999. If you want to represent the number 12345, you can't do it as a 3-digit number — you'll need at least a 5-digit number. And it's the same for the binary numbers that C variables are represented as, except that it's the number of bits we care about (8, 16, 32, or 64) instead of the number of digits. – Steve Summit Sep 13 '21 at 19:15

2 Answers2

1

N bits can represent 2N different values:

1 bit,  2 values - 0, 1
2 bits, 4 values - 00, 01, 10, 11
3 bits, 8 values - 000, 001, 010, 011, 100, 101, 110, 111

etc.

A type that's 8 bits wide can represent 28, or 256 different values. A type that's 16 bits wide1 can represent 216, or 65536 different values.

The same bit patterns can be interpreted different ways. There are several different ways to represent signed integer values - two's complement, ones' complement, and sign-magnitude are the three you're most likely to hear about, and two's complement is by far the most common. Here's a 4-bit example showing how bits are interpreted in each scheme:

Bits    Unsigned    Two's Cmp    Ones' Cmp    Sign-mag
----    --------    ---------    ---------    --------
0000           0            0            0           0     
0001           1            1            1           1
0010           2            2            2           2
0011           3            3            3           3
0100           4            4            4           4
0101           5            5            5           5
0110           6            6            6           6
0111           7            7            7           7
1000           8           -8           -7          -0
1001           9           -7           -6          -1
1010          10           -6           -5          -2
1011          11           -5           -4          -3
1100          12           -4           -3          -4
1101          13           -3           -2          -5
1110          14           -2           -1          -6
1111          15           -1           -0          -7

4 bits can represent 16 different values, but those values depend on how the bits are interpreted.

Thus, unsigned char represents values in the range [0..255] (assuming CHAR_BIT == 8), where signed char represents values in the range [-128..127] (assuming CHAR_BIT == 8 and two's complement representation for signed values). It's the same number of values (256), just over different ranges.

Similarly, a 32-bit float can represent the same number of values as a 32-bit int (4294967296), but they are interpreted differently. The bit pattern 439d145a16 can represent either the floating point value 3.14159 or the integer value 1134367834 (assuming IEEE-754 single-precision floating point).


  1. C allows for the presence of padding bits that don't contribute to the value representation for types other than unsigned char, but you're unlikely to see anything like that on modern hardware.
John Bode
  • 119,563
  • 19
  • 122
  • 198
0

The variables are stored in the memory which consists of bytes. Each variable type differs in the way it represents these bytes and the number of bytes it reserves. For your example, a char is contained in a 1-byte memory block, and the byte holds 8-bits. When you represent these bits in an unsigned number, the minimum number you can get is 0 (0b00000000) and the maximum number is 255 (0b11111111). Back to the char example, the char is being represented in a signed way, search for 2's complement to get more details, this representation can hold the values you mentioned by changing the way the byte is translated from the previous method. for example the number (0b00000000) is still 0, but the number (0b11111111) is -1.

S.Murtadha
  • 42
  • 10