IEEE 754 float32 values in [0, 1] – live WebGPU

Every glowing dot is a real single-precision float generated with the exact hardware formula:

value = (1 + mantissa) × 2exponent
exponent runs from –126 to 0  |  mantissa is a fraction in [0, 1)

Linear scale = true number line → almost all values sit extremely close to zero (the bright bar).
Log scale = position ∝ log₁₀(value) → shows that floats exist at every order of magnitude from ~10⁻³⁸ up to 1.

WebGPU: instance buffer holds every float + phase. Vertex shader maps value → screen X (linear/log) + bobbing. Fragment shader makes soft circles. Additive blending shows density.

Current: Log scale
WebGPU ready · 0 / 0 points
0
1
10⁻³⁰
10⁻²⁰
10⁻¹⁰
10⁻⁵
0.01
0.1

Scientific Notation & Computing

In scientific notation a number is written as a significand (also called the mantissa) multiplied by a power of ten (or two in binary).

Example: 5.3266 × 10³
→ The part 5.3266 is the significand (mantissa).
→ The part 10³ is the exponent that scales the value.

Value scaling: The significand carries the precision (the significant digits), while the exponent controls the magnitude (how large or small the number is). Together they let computers represent both very large and very tiny numbers with a fixed number of bits.

In IEEE 754 binary floating-point the significand is stored in normalized form (usually with a leading 1 that is implicit). That is exactly why the formula you see in the visualization is written as (1 + mantissa) × 2exponent.

Color Meaning

Cyan / blue points (left side) = very small floating-point numbers (close to 0).

Pink / magenta points (right side) = floating-point numbers that are relatively close to 1.0 (for example 0.5, 0.75, 0.9, 0.99, etc.).

In Linear scale you see very few pink points because almost all possible float32 values are packed tightly near zero.
In Log scale the pink points become more visible because the scale spreads out the larger magnitudes.

Why This Design Was Intentional (History)

The dense cluster of values near zero that you see on the Linear scale is not an accident — it was a deliberate design choice made by the IEEE 754 committee (led by William Kahan) in the late 1970s / early 1980s.

Approach Spacing of numbers Dynamic range Result
Fixed-point Uniform Very limited Not practical for scientific computing
Floating-point (IEEE 754) Denser near zero Extremely wide What we use today

The designers prioritized relative accuracy and a huge dynamic range over uniform spacing.

Exact Number of Representable Values

Yes — there is a fixed, deterministic number of values that IEEE 754 float32 can represent.

Category Count Notes
Total possible bit patterns 4,294,967,296 (2³²) Every possible 32-bit combination
Distinct finite real numbers 4,278,190,079 Counting +0 and –0 as the same value
Finite bit patterns (incl. ±0) 4,278,190,080 Treating +0 and –0 as distinct
+Infinity and –Infinity 2
NaN payloads 16,777,214 Many different NaN bit patterns

Positive finite numbers (including +0): 2,139,095,040
Negative finite numbers (including –0): 2,139,095,040

Of the positive numbers:
• 1 zero
• 8,388,607 denormalized (subnormal) numbers
• 2,130,706,432 normal numbers (254 exponents × 2²³ significands)

In the closed interval [0, 1] there are exactly 1,056,964,610 distinct non-negative float32 values
(this is what the visualization is sampling from).

Where IEEE 754 Appears in Real Systems

1. CPU & GPU Hardware
Modern processors contain dedicated Floating-Point Units (FPUs). The silicon is designed to implement the exact IEEE 754 rules (bit layout, rounding, NaN, Infinity, denormals). Instruction sets such as x86 SSE/AVX, ARM NEON, and RISC-V all have special floating-point instructions that follow the standard.

2. Compilers
Compilers must respect IEEE 754 when generating code. They cannot freely rearrange floating-point operations the way they can with integers. Flags like -ffast-math deliberately break strict compliance for speed.

3. Software
Almost all numerical software depends on it: games, graphics, machine learning, scientific simulations, finance, physics engines, etc.

Why This Knowledge Matters + Concrete Examples

Here are real situations where understanding the non-uniform density and other IEEE 754 behaviors prevents bugs or performance problems:

Example 1 – Random numbers in [0, 1)

// Bad: biased let r = Math.random(); // Better for uniform float distribution let r = (Math.random() * 0x1000000) / 0x1000000;

Because of the density near zero, a naïve 32-bit integer divided by 2³² produces a biased distribution.

Example 2 – Comparing floating-point numbers

// Dangerous if (a === b) { ... } // Better if (Math.abs(a - b) < 1e-6) { ... } // or use a relative epsilon

Two calculations that should be equal often differ by a few units in the last place (ULPs).

Example 3 – Denormal performance trap

// Can become extremely slow on many CPUs let x = 1e-40; for (let i = 0; i < 1000000; i++) { x = x * 0.5; // eventually hits denormals → big slowdown }

Denormalized numbers (the extra values very close to zero) are handled in hardware much more slowly on most CPUs.

Example 4 – Catastrophic cancellation

let a = 1.0000001; let b = 1.0000000; let diff = a - b; // result has almost no precision left

Subtracting two nearly equal numbers destroys significant digits. This is why many numerical algorithms are carefully rewritten to avoid it.

Understanding the density near zero, the limited number of significand bits, and special values (NaN, Infinity, denormals) helps you write more robust and faster numerical code.