Skip to main content

Section 4.6 Number Types

Every variable in C has a type. The type of a variable determines what values can be stored in the container bound to the variable. We distinguish scalar types and aggregate types. The scalar types in C include different kinds of number representations with different ranges. There are integer types and floating-point types. The integer types char, short, int, and long come in two flavors, unsigned and signed, which are prepended to the type. If no signedness is specified, the type is implicitly signed. If only unsigned, without any further type specifier, is used, it refers to an unsigned int.

For signed integer types, the C Standard [1] does not define which representation is used. In particular, one should not assume that signed values are represented in two's complement and the corresponding arithmetic is used. The unsigned integer types are defined to use modulo arithmetic: They wrap around upon overflow. The Standard also does not specify the sizes of the integer types. It only guarantees the following relationships:

\begin{equation*} 1 = \mathtt{sizeof(char)} \leq \mathtt{sizeof(short)} \leq \mathtt{sizeof(int)} \leq \mathtt{sizeof(long)} \end{equation*}

The sizeof operator in C provides the size of any type. This weak specification is intentional, as it enables correct C implementations on a variety of different computers. It is however also the cause of many software bugs, since it is easy for uninformed programmers to make too strong assumptions about the semantics of C. For ordinary calculations, we use int, since an int usually corresponds to a machine word.

Floating-point types are used in numerical programs. They represent an excerpt of the rational numbers. As there are is only a finite number of bits available to represent a value, computations with floating-point values generally involve running errors. In longer-running programs, these can propagate without notice, leading to program errors that are hard to detect. It is tempting to program with floating-point values as if they were rational or even real numbers. However, floating-point arithmetic violates many of the essential properties of real and rational arithmetic that we are used to rely on, such as the associative law. C provides three floating-point types: float, double, long double. They differ in their size (and therefore in their range and precision).