(See alsotype for type system overview andthe list of type-related utilities that are provided by the C library.)
Boolean typeNote thatconversion to_Bool(until C23)bool(since C23) does not work the same as conversion to other integer types:(bool)0.5 evaluates totrue, whereas(int)0.5 evaluates to0. | (since C99) |
Note that the standard library also definestypedef nameswchar_t,char16_t andchar32_t(since C11) to represent wide charactersandchar8_t for UTF-8 characters(since C23).
| (since C99) |
| (since C23) |
Note: as with all type specifiers, any order is permitted:unsignedlonglongint andlongintunsignedlong name the same type.
The following table summarizes all available integer types and their properties:
| Type specifier | Equivalent type | Width in bits by data model | ||||
|---|---|---|---|---|---|---|
| C standard | LP32 | ILP32 | LLP64 | LP64 | ||
char | char | at least 8 | 8 | 8 | 8 | 8 |
signedchar | signedchar | |||||
unsignedchar | unsignedchar | |||||
short | shortint | at least 16 | 16 | 16 | 16 | 16 |
shortint | ||||||
signedshort | ||||||
signedshortint | ||||||
unsignedshort | unsignedshortint | |||||
unsignedshortint | ||||||
int | int | at least 16 | 16 | 32 | 32 | 32 |
signed | ||||||
signedint | ||||||
unsigned | unsignedint | |||||
unsignedint | ||||||
long | longint | at least 32 | 32 | 32 | 32 | 64 |
longint | ||||||
signedlong | ||||||
signedlongint | ||||||
unsignedlong | unsignedlongint | |||||
unsignedlongint | ||||||
longlong | longlongint (C99) | at least 64 | 64 | 64 | 64 | 64 |
longlongint | ||||||
signedlonglong | ||||||
signedlonglongint | ||||||
unsignedlonglong | unsignedlonglongint (C99) | |||||
unsignedlonglongint | ||||||
Besides the minimal bit counts, the C Standard guarantees that
≤sizeof(short)≤sizeof(int)≤sizeof(long)≤sizeof(longlong).Note: this allows the extreme case in whichbyte are sized 64 bits, all types (includingchar) are 64 bits wide, andsizeof returns1 for every type.
Note: integer arithmetic is defined differently for the signed and unsigned integer types. Seearithmetic operators, in particularinteger overflows.
The choices made by each implementation about the sizes of the fundamental types are collectively known asdata model. Four data models found wide acceptance:
32 bit systems:
64 bit systems:
Other models are very rare. For example,ILP64 (8/8/8:int,long, and pointer are 64-bit) only appeared in some early 64-bit Unix systems (e.g.Unicos on Cray).
Note that exact-width integer types are available in<stdint.h> since C99.
C has threeor six(since C23) types for representing real floating-point values:
| (since C23) |
Floating-point types may support special values:
Real floating-point numbers may be used witharithmetic operators+-/* and various mathematical functions from<math.h>. Both built-in operators and library functions may raise floating-point exceptions and seterrno as described inmath_errhandling.
Floating-point expressions may have greater range and precision than indicated by their types, seeFLT_EVAL_METHOD.Assignment,return, andcast force the range and precision to the one associated with the declared type.
Floating-point expressions may also becontracted, that is, calculated as if all intermediate values have infinite range and precision, see#pragma STDC FP_CONTRACT.
Some operations on floating-point numbers are affected by and modify the state ofthe floating-point environment (most notably, the rounding direction).
Implicit conversions are defined between real floating types and integer, complex, and imaginary types.
SeeLimits of floating-point types and the<math.h> library for additional details, limits, and properties of the floating-point types.
Complex floating typesComplex floating types model the mathematicalcomplex number, that is the numbers that can be written as a sum of a real number and a real number multiplied by the imaginary unit:a + bi The three complex types are
Note: as with all type specifiers, any order is permitted:longdoublecomplex,complexlongdouble, and evendoublecomplexlong name the same type. Run this code Output: 1/(1.0+2.0i) = 0.2-0.4i
Each complex type has the sameobject representation andalignment requirements as anarray of two elements of the corresponding real type (float forfloatcomplex,double fordoublecomplex,longdouble forlongdoublecomplex). The first element of the array holds the real part, and the second element of the array holds the imaginary component. Complex numbers may be used witharithmetic operators Increment and decrement are not defined for complex types. Relational operators are not defined for complex types (there is no notion of "less than").
In order to support the one-infinity model of complex number arithmetic, C regards any complex value with at least one infinite part as an infinity even if its other part is a NaN, guarantees that all operators and functions honor basic properties of infinities and providescproj to map all infinities to the canonical one (seearithmetic operators for the exact rules). Run this code #include <complex.h>#include <math.h>#include <stdio.h> int main(void){doublecomplex z=(1+0*I)*(INFINITY+ I*INFINITY);// textbook formula would give// (1+i0)(∞+i∞) ⇒ (1×∞ – 0×∞) + i(0×∞+1×∞) ⇒ NaN + I*NaN// but C gives a complex infinityprintf("%f%+f*i\n",creal(z),cimag(z)); // textbook formula would give// cexp(∞+iNaN) ⇒ exp(∞)×(cis(NaN)) ⇒ NaN + I*NaN// but C gives ±∞+i*nandoublecomplex y=cexp(INFINITY+ I*NAN);printf("%f%+f*i\n",creal(y),cimag(y));} Possible output: inf+inf*i inf+nan*i C also treats multiple infinities so as to preserve directional information where possible, despite the inherent limitations of the Cartesian representation: multiplying the imaginary unit by real infinity gives the correctly-signed imaginary infinity: i × ∞ = i∞. Also, i × (∞ – i∞) = ∞ + i∞ indicates the reasonable quadrant.
Imaginary floating typesImaginary floating types model the mathematicalimaginary numbers, that is numbers that can be written as a real number multiplied by the imaginary unit:biThe three imaginary types are
Note: as with all type specifiers, any order is permitted:longdoubleimaginary,imaginarylongdouble, and evendoubleimaginarylong name the same type. Run this code Output: 1/(3.0i) = -0.3i
Each of the three imaginary types has the sameobject representation andalignment requirement as itscorresponding real type (float forfloatimaginary,double fordoubleimaginary,longdouble forlongdoubleimaginary). Note: despite that, imaginary types are distinct andnot compatible with their corresponding real types, which prohibits aliasing. Imaginary numbers may be used witharithmetic operators Increment and decrement are not defined for imaginary types.
The imaginary numbers make it possible to express all complex numbers using the natural notationx+ I*y (whereI is defined as_Imaginary_I). Without imaginary types, certain special complex values cannot be created naturally. For example, ifI is defined as_Complex_I, then writing0.0+ I*INFINITY gives NaN as the real part, andCMPLX(0.0, INFINITY) must be used instead. Same goes for the numbers with the negative zero imaginary component, which are meaningful when working with the library functions with branch cuts, such ascsqrt:1.0-0.0*I results in the positive zero imaginary component ifI is defined as_Complex_I and the negative zero imaginary part requires the use ofCMPLX orconj. Imaginary types also simplify implementations; multiplication of an imaginary by a complex can be implemented straightforwardly with two multiplications if the imaginary types are supported, instead of four multiplications and two additions. | (since C99) |
The following table provides a reference for the limits of common numeric representations.
Prior to C23, the C Standard allowed any signed integer representation, and the minimum guaranteed range of N-bit signed integers was from\(\scriptsize -(2^{N-1}-1)\)-(2N-1
-1) to\(\scriptsize +2^{N-1}-1\)+2N-1
-1 (e.g.-127 to127 for a signed 8-bit type), which corresponds to the limits ofone's complement orsign-and-magnitude.
However, all popular data models (including all of ILP32, LP32, LP64, LLP64) and almost all C compilers usetwo's complement representation (the only known exceptions are some compilers for UNISYS), and as of C23, it is the only representation allowed by the standard, with the guaranteed range from\(\scriptsize -2^{N-1}\)-2N-1
to\(\scriptsize +2^{N-1}-1\)+2N-1
-1 (e.g.-128 to127 for a signed 8-bit type).
| Type | Size in bits | Format | Value range | |
|---|---|---|---|---|
| Approximate | Exact | |||
| character | 8 | signed | −128 to127 | |
| unsigned | 0 to255 | |||
| 16 | UTF-16 | 0 to65535 | ||
| 32 | UTF-32 | 0 to1114111 (0x10ffff) | ||
| integer | 16 | signed | ± 3.27 · 104 | −32768 to32767 |
| unsigned | 0 to6.55 · 104 | 0 to65535 | ||
| 32 | signed | ± 2.14 · 109 | −2,147,483,648 to2,147,483,647 | |
| unsigned | 0 to4.29 · 109 | 0 to4,294,967,295 | ||
| 64 | signed | ± 9.22 · 1018 | −9,223,372,036,854,775,808 to9,223,372,036,854,775,807 | |
| unsigned | 0 to1.84 · 1019 | 0 to18,446,744,073,709,551,615 | ||
| binary floating- point | 32 | IEEE-754 |
|
|
| 64 | IEEE-754 |
|
| |
| 80[note 1] | x86 |
|
| |
| 128 | IEEE-754 |
|
| |
| decimal floating- point | 32 | IEEE-754 |
| |
| 64 | IEEE-754 |
| ||
| 128 | IEEE-754 |
| ||
Note: actual (as opposed to guaranteed minimal) ranges are available in the library headers<limits.h> and<float.h>.
C++ documentation forFundamental types |