Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

The double keyword in C++ designates a fundamental data type used to represent double-precision floating-point numbers. It is the default type for floating-point literals in C++ and typically adheres to the IEEE 754 binary64 standard, providing a larger range and higher precision than the standard single-precision float type.

Technical Specifications

  • Memory Size: Typically 8 bytes (64 bits). The C++ standard strictly guarantees sizeof(double) >= sizeof(float).
  • Precision: 15 to 17 significant decimal digits.
  • Magnitude Range: Approximately ±2.22507×10308\pm 2.22507 \times 10^{-308} to ±1.79769×10308\pm 1.79769 \times 10^{308}.
  • Limits Header: Architecture-specific limits and properties can be queried at compile-time using std::numeric_limits<double> from the <limits> library.

Memory Layout (IEEE 754 binary64)

At the hardware level, a 64-bit double is structurally divided into three distinct bit-fields:
  1. Sign bit: 1 bit (0 indicates positive, 1 indicates negative).
  2. Exponent: 11 bits (uses an offset bias of 1023).
  3. Mantissa (Significand): 52 bits (stores the fractional part, utilizing an implicit leading 1 for normalized numbers, effectively yielding 53 bits of precision).

Syntax and Initialization

Floating-point literals in source code are evaluated as double by the compiler by default, unless explicitly suffixed with f or F (which designates a float) or l or L (which designates a long double).
// Standard decimal initialization
double pi = 3.141592653589793;

// Scientific (exponential) notation
double avogadro = 6.022e23;   // 6.022 * 10^23
double planck = 6.626e-34;    // 6.626 * 10^-34

// Uniform (brace) initialization
double exact_value { 42.0 };

// Hexadecimal floating-point literal (introduced in C++17)
// Format: 0x[significand]p[exponent in base 2]
double hex_float = 0x1.fp3;   // (1 + 15/16) * 2^3 = 15.5

Type Promotion and Conversion

In expressions involving mixed arithmetic types, C++ applies the “usual arithmetic conversions” on a per-operator basis, dictated by operator precedence and associativity, rather than across the entire statement at once.
int scalar = 5;
float offset = 2.5f;

// Evaluated left-to-right: (scalar + offset) + 1.2
double result = scalar + offset + 1.2; 
In the example above, addition is left-associative. The compiler evaluates scalar + offset first. The int is converted to a float, and the intermediate result is calculated as a float. Only then is that intermediate float promoted to a double for the final addition with the double literal 1.2. This per-operator evaluation can lead to unexpected precision loss if a large integer is implicitly converted to a float during an intermediate step before ultimately being promoted to a double.

Special Values

The double type supports specific non-numeric states defined by the IEEE 754 standard to handle mathematical anomalies:
  • NaN (Not a Number): Represents undefined or unrepresentable operations (e.g., std::sqrt(-1.0)).
  • Infinity (+Inf, -Inf): Represents values exceeding the maximum representable range (overflow).
Note: While the IEEE 754 standard dictates that floating-point division by zero (e.g., 1.0 / 0.0) produces Infinity, the core C++ standard explicitly defines division by zero as Undefined Behavior (UB) for all arithmetic types. To safely utilize special values, they should be generated via the standard library rather than relying on compiler-specific UB handling.
#include <cmath>
#include <limits>

// Generating special values safely via the standard library
double pos_inf = std::numeric_limits<double>::infinity();
double not_a_num = std::numeric_limits<double>::quiet_NaN();

// Checking for special values
bool is_infinite = std::isinf(pos_inf); // Returns true
bool is_nan = std::isnan(not_a_num);    // Returns true
Master C++ with Deep Grasping Methodology!Learn More