The C Path — learn C, visually

🧮 Foundations — Before C

Floating point: scientific notation in bits

⏱ 14 min · free interactive lesson · quizzes, visualizations & a real compiler

▶ Open the interactive lesson — free, no signup
Why you're learning this

Type 0.1 + 0.2 into almost any programming language and you can get back 0.30000000000000004. That famous glitch is not a bug — it's how every computer on Earth stores decimal numbers, and it's the reason banks never store money this way. By the end of this lesson the weirdness will make perfect sense, and you'll know the one comparison mistake with decimals that trips up nearly every beginner.

Integers can't hold 3.14 or 0.001. For real numbers, C gives you float (32-bit) and double (64-bit), both using the IEEE 754 standard — a rulebook nearly every computer agrees on, and essentially binary scientific notation.

Three fields in one number

Just like 6.022 × 10²³ has a sign, digits, and an exponent, a float splits its 32 bits into:

Value = (−1)sign × 1.mantissa × 2exponent−127

This spot has an interactive float32 widget — open the interactive lesson to play with it.

🧠 Checkpoint: A 32-bit float splits its bits as…

  • 8 sign, 8 exp, 16 mantissa
  • 1 sign, 8 exp, 23 mantissa
  • 1 sign, 15 exp, 16 mantissa
  • 2 sign, 10 exp, 20 mantissa
Show answer

1 sign, 8 exp, 23 mantissa — 1 + 8 + 23 = 32. A double is 1 + 11 + 52 = 64 bits.

The famous 0.1 problem

pointone.c
#include <stdio.h>

int main(void) {
    double sum = 0.0;
    for (int i = 0; i < 10; i++)
        sum += 0.1;

    printf("sum        = %.17f\n", sum);
    printf("sum == 1.0 ? %s\n", sum == 1.0 ? "yes" : "NO!");
    return 0;
}
terminal
$ gcc pointone.c -o pointone && ./pointone
sum        = 0.99999999999999989
sum == 1.0 ? NO!

Why?! Because 0.1 cannot be written exactly in binary — it's an infinite repeating fraction (0.000110011001100…), just like 1/3 = 0.333… in decimal. The computer stores the nearest representable value, and tiny errors accumulate.

⚠️

Golden rule: never compare floats with ==. Compare against a tolerance: fabs(a - b) < 1e-9. And never use floats for money — count cents in integers instead.

🧠 Checkpoint: Why does 0.1 + 0.2 != 0.3 in floating point?

  • A compiler bug
  • 0.1, 0.2 and 0.3 have no exact binary representation
  • Floats can only store integers scaled by 2
  • printf rounds incorrectly
Show answer

0.1, 0.2 and 0.3 have no exact binary representation — Like 1/3 in decimal, 1/10 is an infinite repeating fraction in binary. Each constant is rounded to the nearest representable double, and the sums of the roundings differ.

Special values

IEEE 754 reserves exponent patterns for weird-but-useful values:

valuehow you get itfun fact
+∞ / −∞1.0 / 0.0float division by zero doesn't crash!
NaN (not-a-number)0.0 / 0.0, sqrt(-1)NaN ≠ NaN — the only value not equal to itself
−0.0-1.0 * 0.0equal to +0.0, but prints with a minus
denormalsvalues < ~1.2×10⁻³⁸graceful fade to zero (with reduced precision)

🧠 Checkpoint: Which comparison is true in IEEE 754?

  • NaN == NaN
  • -0.0 == 0.0
  • INFINITY == NAN
  • 1.0/0.0 == 0.0
Show answer

-0.0 == 0.0 — Negative zero compares equal to positive zero. NaN is never equal to anything — even itself; that is actually how isnan() can be implemented.

💡

float vs double: float gives ~7 significant decimal digits, double ~15–16. In C, unsuffixed literals like 3.14 are double; write 3.14f for a float. Default to double unless memory is tight.

▶ Practice this lesson interactively (with live gcc)