Standard Floating-Point Types in C Explained

The C programming language provides several native floating-point types designed to balance numerical range, precision, and hardware performance. While traditional C standards specify three primary real floating-point types—float, double, and long double—later standard revisions such as C99 and C23 expanded native language support to include complex numbers, interchange floating formats, and decimal floating-point representations. This guide outlines every floating-point type natively defined by the ISO C standard and explains their roles in systems programming.

Standard Real Floating-Point Types

The core C standard defines three basic floating-point types to represent real numbers:

  • float: Typically implemented as a single-precision 32-bit format conforming to IEEE 754 (IEC 60559). It provides at least 6 decimal digits of precision and is commonly used when memory conservation is prioritized over extreme numerical accuracy.
  • double: Typically implemented as a double-precision 64-bit IEEE 754 format. It yields at least 10 decimal digits of precision (usually 15 to 17 in practice) and serves as the default floating-point type for mathematical operations and standard library functions in <math.h>.
  • long double: An extended-precision type intended to provide higher precision than double. Depending on the target compiler and architecture, long double may be represented as an 80-bit extended-precision format (common on x86), a true 128-bit quadruple-precision format, or an alias identical to a 64-bit double.

The properties, limits, and minimum precision guarantees for these types are standardized in the <float.h> header using constants such as FLT_DIG, DBL_MAX, and LDBL_EPSILON.

Complex and Imaginary Types (C99)

Starting with the C99 standard, C introduced native keywords for complex and pure imaginary arithmetic:

  • float _Complex, double _Complex, and long double _Complex: Store a pair of floating-point values representing the real and imaginary components. When <complex.h> is included, these types can be written using the convenience macro complex (e.g., double complex).
  • float _Imaginary, double _Imaginary, and long double _Imaginary: Optional types representing pure imaginary numbers without allocating memory for a real component.

Fixed-Width and Extended Types (C23)

The C23 standard adopted parts of ISO/IEC TS 18661 to standardize fixed-width binary and decimal floating-point representations directly into the language grammar:

  • Interchange Floating Types (_FloatN): Optional types that explicitly map to IEEE 754 binary formats of fixed widths, specifically _Float16, _Float32, _Float64, and _Float128.
  • Extended Floating Types (_FloatNx): Types providing at least the precision and range of the corresponding standard type with extra precision or exponent range (e.g., _Float32x, _Float64x).
  • Decimal Floating Types (_DecimalN and _DecimalNx): Native types intended for financial and commercial computing where base-10 rounding is required, including _Decimal32, _Decimal64, and _Decimal128.