5.7 Numeric Literals

Numeric literals allow you to specify fixed numeric values directly in your source code.

  • Integer Literals:

    • Default to i32 if the type cannot be inferred otherwise from context.
    • Can use underscores _ as visual separators for readability (e.g., 1_000_000). These are ignored by the compiler.
    • Can have type suffixes to specify the exact integer type: 10u8, 20i32, 30usize.
    • Supports different bases using prefixes:
      • Decimal: 98_222 (no prefix)
      • Hexadecimal: 0xff (prefix 0x)
      • Octal: 0o77 (prefix 0o)
      • Binary: 0b1111_0000 (prefix 0b)
    • Byte literals represent single bytes (u8) using ASCII values: b'A' (the u8 value 65).
  • Floating-Point Literals:

    • Default to f64 (double precision).
    • Can use underscores: 1_234.567_890.
    • Requires a digit before a decimal point (0.5, not .5).
    • A trailing decimal point is allowed (1., equivalent to 1.0).
    • Can use exponent notation (e or E): 1.23e4 (1.23 * 10^4), 0.5E-2 (0.5 * 10^-2).
    • To specify f32 (single precision) when the type cannot be inferred from context, use the f32 suffix: 2.0f32.
fn main() {
    let decimal = 100_000;       // i32 by default
    let hex = 0xEADBEEF;        // i32 by default
    let octal = 0o77;            // i32 by default
    let binary = 0b1101_0101;   // i32 by default
    let byte = b'X';             // u8 (value 88)

    let float_def = 3.14;        // f64 by default
    let float_f32 = 2.718f32;    // f32 explicit suffix
    let float_exp = 6.022e23;    // f64

    println!("Dec: {}, Hex: {}, Oct: {}, Bin: {}, Byte: {}", decimal, hex, octal, binary, byte);
    println!("f64: {}, f32: {}, Exp: {}", float_def, float_f32, float_exp);

    // Type inference example:
    let values: [f32; 3] = [1.0, 2.0, 3.0]; // Here, literals are known to be f32 from array type
    let sum = values[0] + 0.5; // 0.5 here must be f32 due to context, suffix not needed
    println!("Sum (f32): {}", sum);

    let value_f64 = 1.0; // f64
    // let mixed_sum = values[0] + value_f64; // Compile Error: mismatched types f32 and f64
}

If the compiler cannot unambiguously determine the required numeric type from the context (e.g., assigning to an untyped variable, or initial parsing), you must provide either a type suffix on the literal or a type annotation on the variable.