TCthomas.caron
~ / lab / float-scope
03·live·2026.04

Float64 microscope

Why 0.1 + 0.2 ≠ 0.3, at the bit level.
stack
IEEE-754 · Float64Array · BigInt
kind
decoder
status
live

Every JavaScript number is an IEEE-754 binary64: 1 sign bit, 11 exponent bits, 52 mantissa bits. Paste a value, see the bits, step through representable neighbors, and watch why 0.1 + 0.2 lands one ulp past 0.3.

sign
exponent · 11
mantissa · 52
0x3fd3·3333·3333·3334
decoded
value
0.30000000000000004
category
normal
sign
0 (+)
raw exp
1021 / 2047
unbiased
-2
mantissa
900719925474100
ulp
5.551e-17
representable neighbors
prev0.3
this0.30000000000000004
next0.3000000000000001
gap = 5.551e-17
memory · eight bytes

The same bits, laid out byte by byte. IEEE logical order reads left-to-right from sign bit to mantissa tail. Your CPU (if x86 or ARM) stores it reversed.

IEEE logical (big-endian)
sign bit first · how the spec is written
off
hex
binary
chr
·
00
3f
S/E
01
d3
E/M
02
33
M
03
33
M
04
33
M
05
33
M
06
33
M
07
34
M
machine RAM (little-endian)
low byte first · how x86 / ARM stores it
off
hex
binary
chr
·
00
34
M
01
33
M
02
33
M
03
33
M
04
33
M
05
33
M
06
d3
E/M
07
3f
S/E
0.1 + 0.2 ≠ 0.3

Both sides round to different binary64 values. The sum of 0.1 and 0.2 overshoots 0.3 by exactly one ulp, which is the minimum possible gap at this magnitude. This is not a bug; it is what "base-2 float" means.

0.1 + 0.2
0.30000000000000004
0x3fd3333333333334
0.3
0.3
0x3fd3333333333333
offset: 1 ulp

Decoded with Float64Array + BigUint64Array via a shared ArrayBuffer. Prev/next walk by ±1 on the raw bit integer, which is the IEEE-754 "next representable" operation.

thesis

Paste a float, see sign / exponent / mantissa bits, the nearest representable value, ulp distance, round-trip through decimal. Walk through catastrophic cancellation, subnormals, and NaN payloads.

← back to lab
thomas.caron — software developer
montréal, qc · UTC−04:00
built with vite + cloudflare workers
© 2026 — last deploy: 2026.05.07 ·privacy