signexponentfractionthe four IEEE 754 binary formats, drawn to scale

IEEE 754-2019 · binary interchange format · 64 bits

binary64

The format of science, and of JavaScript

A 64-bit IEEE 754 number: one sign bit, eleven bits of exponent, fifty-two bits of fraction. The default number of nearly every scientific library, of Python, R, MATLAB and Julia, and the only number JavaScript has.

Also called double precision, double, f64, REAL*8, Number, float (Python), np.float64.

sign · 1 bitexponent · 11 bitsfraction · 52 bits

The number above is 0.1, the value the inspector below opens on. Change it there and this changes with it.

Anatomy

What the 64 bits mean

A binary64 value is a sign, a biased exponent and a fraction, packed as s · e · f from the most significant bit down. When the exponent field is neither all zeros nor all ones the value is (−1)s × 1.f × 2e − 1023: the leading 1 is implied, so 52 stored bits give 53 bits of precision. All zeros in the exponent means a subnormal, (−1)s × 0.f × 2-1022, which lets the format lose precision gradually rather than dropping to zero. All ones means infinity when the fraction is zero and a NaN otherwise; the fraction's top bit says whether the NaN is quiet or signaling.

parameterbinary64what it is
w11exponent field width, in bits
t52fraction field width, in bits
p53precision, in bits: t plus the implied leading 1
emax1023largest exponent of a finite value
emin-1022smallest exponent of a normal value, 1 − emax
bias1023added to the exponent before it is stored, so the field is unsigned
encoding8 bytes16 hex digits; little-endian in memory on every mainstream machine
InspectorAny number, to every bit and every digit

Type a decimal (0.1, 1e10, -0, inf, nan), a hexadecimal float (0x1.8p3), or a raw encoding (0x followed by exactly 16 hex digits). Click a bit to flip it. The decimal-to-binary conversion is correctly rounded under the attribute you pick, and "inexact" tells you the decimal you typed is not a binary64 value, only nearest to one. The exact decimal expansion has no digit limit: the library's conversion is exact at every length, which is what makes this widget possible.

What it can hold

15.95 decimal digits, and every integer to 9,007,199,254,740,992

Precision is 53 bits, which is 15.95 decimal digits: any decimal with 15 significant digits survives a round trip through binary64, and 17 digits are enough to write any binary64 value down so that it reads back to the same bits. Every integer up to 253 = 9,007,199,254,740,992 is exact; above it the spacing between representable numbers is 2, then 4, then 8, and an integer that lands between them is rounded to a neighbour. The largest finite value is about 1.80e308, the smallest normal about 2.23e-308, and the subnormals reach down to 2-1074, about 4.94e-324.

The spacing is what matters in practice. Between two consecutive powers of two the representable values are evenly spaced, 252 of them per binade, and the spacing doubles with every binade. Relative to the value it is always between 2−53 and 2−52; absolute, it depends entirely on how big the value is.

SpacingHow far apart neighbouring values are, at every magnitude

Where it lives

Every CPU natively, every language by default, and one JavaScript

binary64 has been in silicon since the 8087 in 1980. Every desktop, server and phone processor computes it in hardware at close to its binary32 rate, and it is the number type a language gives you when you do not ask for one: double in C, C++, Java and C#, float in Python, Number in JavaScript, REAL*8 or real(8) in Fortran, the default of R, MATLAB, Julia, NumPy and every spreadsheet. When a scientific paper says "floating point" without a width, it means this.

Graphics processors are the exception that matters. A GPU is built for binary32; its binary64 rate ranges from half the binary32 rate on parts sold for simulation to one thirty-second or one sixty-fourth on parts sold for games and machine learning. The same CUDA kernel can be forty times slower on one card than on another with the same nominal peak, and that is the first thing to check before moving a double-precision workload to a GPU.

wherehow it is spellednative?
C, C++doubleyes; beware long double, which is a different format on every platform
Java, C#, Go, Rust, Swift, Kotlindouble · double · float64 · f64 · Double · Doubleyes; Java made strict IEEE evaluation the only mode in Java 17 (JEP 306)
JavaScript, TypeScriptNumberyes, and it is the only number type: integers above 253 need BigInt
Pythonfloatyes; decimal and fractions are the alternatives when it is the wrong tool
Fortranreal(kind=real64) · REAL*8 · double precisionyes
NumPy, R, MATLAB, Juliafloat64 · numeric · double · Float64yes, the default
x86-64, ARM64, RISC-V, POWERSSE2 / NEON / D extension / VSXhardware, including fused multiply-add on everything made after about 2013
GPUsdoublehardware, at 1/2 to 1/64 of the binary32 rate depending on the part
the cft-fp256 tileCFT_FP644 lanes per beat at 135 MHz. One tile is 1.1x behind an x86-64 workstation's own FPU on this format; it carries binary64 so that one contract covers the whole ladder, not to win here (measured)

Where it breaks

Fifteen digits is a lot, until it is not

Most binary64 trouble is one of four things. A decimal that has no binary64 value, so what you typed is not what you stored. An integer past 253, where the spacing between representable numbers is already 2. A sum whose answer depends on the order the terms were added, which is every parallel reduction ever written. And a transcendental function whose last bit is left to the library, so sin on one machine is not sin on another. Each case below is computed here, by the library this page runs, and where your browser has an opinion of its own it is shown beside the contract's and compared bit for bit.

Every case above is computed in this tab by the same library that scores itself against the published vectors at the bottom of the page. Where your browser has the format natively, its own answer is shown beside the contract's, and the two are compared bit for bit.

Rounding and flags

Five ways to round, five things that can go wrong

Every arithmetic operation computes the exact result and then rounds it once, under one of five attributes: to nearest with ties to even (the default everywhere), toward zero, toward −∞, toward +∞, and to nearest with ties away from zero. The directed attributes are how interval arithmetic gets rigorous bounds; ties-to-away is what some decimal conventions expect. Alongside the result, five flags record what happened: inexact when rounding changed the value, underflow when a tiny result was also inexact, overflow when the exact result was too large, divideByZero for a finite divided by zero, and invalid for an operation with no meaningful answer, such as 0/0 or ∞ − ∞, which delivers a quiet NaN.

PlaygroundOne operation, all five attributes
attributeresult, 17 digitsencodingflags

The operands are parsed under to-nearest first, so what differs between the rows is only the operation's own rounding. A result that is the same in all five rows was exact.

Tools and libraries

What to reach for at binary64

The hardware does the arithmetic and does it correctly rounded; the tools are for everything around it. Ranked by how often they are the right answer.

toolbest forthe catch
the platform libm (glibc, musl, Apple's, MSVC's)every sin, exp and pow your program callsthe last bit is the vendor's choice; results differ across platforms and versions, legally
CORE-MATH and CRlibmcorrectly rounded binary64 functions, when the last bit must be the same everywherea separate library to link; CORE-MATH's binary32 functions have begun landing in glibc itself
printf("%a"), %.17g, Python's float.hex()writing a double down so it reads back to the same bits17 significant digits are needed for a guaranteed round trip, and the shortest string that works is what repr and JavaScript's String(x) print
Kahan summation, ReproBLAS, and 754-2019's augmentedAdditionsums that do not depend on the order of the terms, or that carry their own errorcompensated sums cost two to four times a plain sum; reproducible ones need every participant to use the same scheme
Herbierewriting an expression so it loses fewer bitsit improves accuracy, not reproducibility; the rewritten form still runs on your libm
MPFR, Julia's BigFloat, Python's mpmathchecking a binary64 answer at more digits than binary64 hasa hundred times slower, and a different exponent range unless you ask for the binary format's
the compiler's switches: -ffp-contract=off, -fexcess-precision=standard, /fp:strictmaking the compiler compute what the source says, one rounding per operation-ffast-math and -Ofast silently undo all of it; check the flags of every library you link
libcft (cft-fp256), software backenda definition of the correct binary64 answer for every operation and all 39 transcendentals, scored against 1,068,915 published cases, in C with no dependencies, in nine languages, in this taba CPU wins on throughput at this format, by design: the library's own arithmetic is integer softfloat, MPFR beats it 6 to 19 times on add, multiply and fma, and the FPGA tile is 1.1x behind a workstation. It is here for the contract, not for speed

Same bits everywhere

Clause 9 is where binary64 stops agreeing

The basic operations of binary64, add, subtract, multiply, divide, square root and fused multiply-add, are correctly rounded on every processor that conforms to IEEE 754, so two machines that both conform get the same bits from the same operands. The disagreement starts one clause later. The standard recommends that sin, exp, pow and the rest of its table 9.1 be correctly rounded and does not require it, so every libm is free to be off by a unit in the last place, and they are, differently. A simulation that calls exp a billion times is a different simulation on macOS and on Linux, and a run cannot be reproduced on a machine that was not the one it ran on.

cft-fp256's answer is to define one exact result for every operation, including all thirty-nine of table 9.1 correctly rounded under all five rounding attributes with exact flags, and to score every implementation of it against that definition. GNU MPFR, the only independent library that reaches this, arbitrates 739,234 transcendental cases with zero value and zero flag mismatches. The widget below asks your browser's Math the same questions.

The evidence this site carries for the definition being binary64 itself and not a look-alike is cft-rebound: REBOUND's IAS15, a fifteenth-order adaptive integrator used in orbital-dynamics research, with every floating-point operation routed through this library. At binary64 its output is REBOUND's own, bit for bit, across 1,264 recorded values, rejected steps and iteration caps included. A library that reproduces a real scientific code's bits computes IEEE binary64. The same program in nine languages, C, C++, Fortran, Python, Rust, Julia, Go, C# and R, prints the checksum 0x04110a4c30c6df4d over this format's vectors on every platform in the project's compatibility record.

This site's own experimentYour browser's Math, against the correctly rounded value

Type an input and compare, or sweep a thousand pseudo-random inputs (a fixed seed, so the same inputs every time) and count how often your browser's function differs from the correctly rounded result in the last bit. Run the same page in another browser and the count changes, because the libm underneath changed. Every difference is one unit in the last place, and every one of them is legal.

Conformance replayThe published binary64 vectors, replayed in this tab
Not run yet.

The sample is the one the library's own conformance page embeds: every 59th line of each published set for this format, plus the first line of any opcode the stride missed, so every opcode class is present. It runs through cft_conformance(), the same C code path every backend of the library is judged by. The full 1,068,915-case sets replay on the conformance page, which accepts the generated files by drag and drop.

Up and down the ladder

When binary64 is enough, measured, and when it is not

The honest bridge to the wider formats is a measurement from cft-rebound's horizon study, which asked how long a binary64 orbit integration stays worth having. Round-off in binary64 is a random walk: over a 64-member ensemble the 90th-percentile phase error of a Kepler orbit grows as 2.1e-16 × orbits1.5, and no step size or tolerance changes that law, because a smaller step only adds steps and round-off with them. It reaches one millionth of an orbit near two million orbits. A binary128 run's error is the method's instead, a ruler rather than a walk, and at a tighter tolerance it holds the same threshold for fifty billion orbits.

So binary64 is entirely sufficient for a regular system under a million orbits at that threshold, for a chaotic system past its Lyapunov horizon where the science is statistical anyway, and for anything whose physics limits it first, which is most things. The niche for a wider format is a phase of a regular system past a few million orbits, a close encounter passed with the energy still the method's, and a result demanded exact rather than close. That is what binary128.com is about.

Down the ladder, binary32 is the right choice when seven digits are enough and the lanes are worth it: graphics, audio, most machine-learning inference, and any array large enough that halving its bytes is the difference between fitting in cache and not.

The number in the inspector travels with you: a neighbouring site opens on the same value, widened exactly or rounded once to its own format, and says so.

Reading

  • IEEE Std 754-2019, IEEE Standard for Floating-Point Arithmetic. The definition; clause 3 has the formats, clause 4 the rounding attributes, clause 5 the operations, clause 9 the recommended functions.
  • David Goldberg, What Every Computer Scientist Should Know About Floating-Point Arithmetic, ACM Computing Surveys, 1991. Still the best first read.
  • Jean-Michel Muller et al., Handbook of Floating-Point Arithmetic, 2nd ed., Birkhäuser, 2018. The reference for how the operations are actually built.
  • Nicholas J. Higham, Accuracy and Stability of Numerical Algorithms, 2nd ed., SIAM, 2002. What the rounding errors do once they are in an algorithm.
  • William Kahan's notes, in particular How Futile are Mindless Assessments of Roundoff in Floating-Point Computation? (2006).