signexponentfractionthe four IEEE 754 binary formats, drawn to scale

IEEE 754-2019 · binary interchange format · 128 bits

binary128

In the standard, almost not in the silicon

A 128-bit IEEE 754 number: one sign bit, fifteen bits of exponent, one hundred and twelve bits of fraction. Thirty-four decimal digits, defined by the standard since 2008, and computed in software on almost every machine you can buy.

Also called quadruple precision, quad, __float128, _Float128, real128, REAL(16), long double (some platforms).

sign · 1 bitexponent · 15 bitsfraction · 112 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 128 bits mean

A binary128 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 − 16383: the leading 1 is implied, so 112 stored bits give 113 bits of precision. All zeros in the exponent means a subnormal, (−1)s × 0.f × 2-16382, 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.

parameterbinary128what it is
w15exponent field width, in bits
t112fraction field width, in bits
p113precision, in bits: t plus the implied leading 1
emax16383largest exponent of a finite value
emin-16382smallest exponent of a normal value, 1 − emax
bias16383added to the exponent before it is stored, so the field is unsigned
encoding16 bytes32 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 32 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 binary128 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

34.02 decimal digits, and every integer to 2^113 (about 1.04e34)

Precision is 113 bits, which is 34.02 decimal digits: any decimal with 34 significant digits survives a round trip through binary128, and 36 digits are enough to write any binary128 value down so that it reads back to the same bits. Every integer up to 2113 = 2^113 (about 1.04e34) 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.19e4932, the smallest normal about 3.36e-4932, and the subnormals reach down to 2-16494, about 6.48e-4966.

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

SpacingHow far apart neighbouring values are, at every magnitude

Where it lives

In the standard since 2008, in hardware almost nowhere

binary128 is the format IEEE 754 defines as its third basic format and almost no processor implements. IBM's POWER9 and later compute it in hardware, IBM's mainframes have for longer, and the RISC-V specification defines a Q extension that nearly nothing fabricates. Everywhere else it is software: GCC's __float128 with libquadmath, C23's _Float128, Fortran's real128, and on some platforms the keyword long double, which is the trap this format is known for. On AArch64 Linux and SPARC long double is binary128. On x86-64 Linux it is the 80-bit x87 format. On Windows and on macOS it is plain binary64. One keyword, three formats, and code that is correct on one platform is silently a different program on the next.

On Apple Silicon there is no __float128 at all, so on that machine the fastest available binary128 is not a compiler type but a library: MPFR at 113 bits, or the software backend that runs this page.

wherehow it is spellednative?
GCC, Clang on x86-64 and AArch64__float128, _Float128 (C23), libquadmathsoftware, compiler-emitted calls into libgcc; fmaq is a slow soft routine
gfortran, ifxreal(kind=real128) · REAL(16)software, the same library
C++std::float128_t (C++23), boost::multiprecision::float128software; C++23's type is optional and not every standard library ships it
long doublelong doublebinary128 on AArch64 Linux, SPARC and POWER (as IBM's double-double on older toolchains); 80-bit on x86-64 Linux; binary64 on MSVC and Apple platforms
Pythonmpmath at 113 bits, gmpy2, cftmpfrno native type; np.longdouble is whatever long double is on that platform, which is usually not this
JuliaQuadmath.jl Float128through libquadmath; BigFloat at 113 bits is MPFR with a wider exponent
Rust, Go, Java, C#, JavaScriptf128 (unstable) · none · none · none · noneRust's f128 exists on nightly behind a feature gate; the others have nothing and need a library
IBM POWER9+, IBM zVSX quad-precision · BFP extendedhardware
RISC-V Q extensionQspecified; implementations are rare
the cft-fp256 tileCFT_FP128hardware: 2 lanes per beat, and the first rung where the card wins. One tile is 4.5x faster than gcc's __float128 on the same machine and four tiles 17.5x; the crossing with MPFR is near 2,700 elements, below which a library call is cheaper than a device call (measured)

Where it breaks

Thirty-four digits, and the ways to not get them

binary128 rarely fails on its own arithmetic. Thirty-four digits absorb the sums, the cancellations and the accumulated drift that break the narrower formats. What breaks is the path to it: a keyword that means three formats, a fused multiply-add that costs forty times a multiply, a NumPy type that is quad on one machine and 80-bit on another, and a decimal literal that was parsed as binary64 before it ever reached the wide type. The cases below show what the format holds exactly, which is the real argument for it: a double's product, a double's sum, the intermediate a binary64 algorithm needed and could not keep.

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, 36 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 binary128

Ranked by how often they are the right answer. The first two are what most binary128 code actually uses; the rest are for when the first two are not there.

toolbest forthe catch
libquadmath with __float128 or _Float128C and C++ on GCC and Clang, x86-64 and AArch64: a real type with arithmetic, sqrtq, expq and the restprinting needs quadmath_snprintf; fmaq multiplies in 20.8 ns and fuses in 817 ns on the same machine, a 39x cliff; absent on Apple Silicon
gfortran real128the constituency the format was standardised for: existing Fortran, one kind parameter widerthe same library underneath, the same fused multiply-add cost
MPFR at 113 bits, with the manual's binary-format recipeany language with an MPFR binding, and the only fast option on Apple Silicon113 bits of precision is not binary128 until the exponent range is narrowed and mpfr_subnormalize runs on every result; and even then MPFR has no signaling NaNs, no payloads and no interchange encoding
Boost.Multiprecision float128C++ that wants operators and streams over the GCC typea wrapper over libquadmath; its cpp_bin_float alternative is a different, non-754 format
Quadmath.jl, mpmathJulia and Python respectivelyQuadmath.jl is libquadmath again; mpmath at 113 bits has MPFR's caveats and Python's speed
double-doubleabout 106 bits of precision from two binary64 values, at hardware speednot binary128: a narrower significand, a binary64 exponent range, and no IEEE semantics at the edges. Fine for accuracy, wrong for interchange
libcft (cft-fp256), software or the tilea definition of the correct binary128 answer for every operation and all 39 transcendentals, with the encodings, the flags, the signaling NaNs and the five rounding attributes the standard specifies; the same bits on a browser, a CPU and the FPGA card. On the card, 4.5x over __float128 on one tile and 17.5x on fourin software it is the reference and not the racer: MPFR beats its softfloat by 6 to 19 times on the basic operations. On the card, below a few thousand elements the call costs more than the arithmetic, and software still wins

Same bits everywhere

At quad, the implementations you can reach disagree with each other

Reproducibility at binary128 has a different problem from binary64's. There is no hardware to define the answer on most machines, so every result is some library's, and the libraries differ: libquadmath and MPFR agree on add, multiply and square root, which are correctly rounded in both, and disagree in the last bit of the transcendentals, where libquadmath is accurate and MPFR is correctly rounded. A value computed with expq and checked with mpfr_exp will not match, and neither is wrong by its own definition.

cft-fp256 defines every operation at this format as correctly rounded, the transcendentals included, and holds itself to that definition against the one independent library that can reach it: GNU MPFR arbitrates 739,234 transcendental cases and 999,000 division and square-root cases at all four formats with zero value and zero flag mismatches. The published conformance vectors are the definition anyone can score their own implementation against, and the replay below runs the binary128 sample of them here. The one program in nine languages prints 0xb815aa4a3a3eb024 over this format's vectors on every platform in the project's compatibility record.

This is also the first rung where the hardware earns its place. The FPGA tile computes binary128 at 2 lanes per beat and reproduces the vectors on silicon to the same bits as the software backend and as this tab: one tile is 4.5x faster than the best software on the same machine, four tiles 17.5x. The point of the card is not that it is fast, though at this format it is; it is that a faster path exists that does not change the answer.

Conformance replayThe published binary128 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

Down when binary64 is enough, which is often; up almost never

binary64 is sufficient far more often than the people buying wider formats expect, and cft-rebound's horizon study says where the line is. For a regular orbit, binary64's phase error reaches one millionth of an orbit near two million orbits at any setting; binary128 at the same tolerance reaches it at twenty-four million, and at a tighter tolerance, for five times the work per orbit, at fifty billion. Below a million orbits, past a chaotic horizon, or wherever the physics limits first, binary64 is the right answer and binary128 buys nothing.

What it buys when it buys something is large. On Burrau's Pythagorean three-body problem, the binary64 solution is lost by t = 66 and the binary128 solution on the same steps runs eighteen decades under it: the two divergence curves are one curve, 260 apart, because the only difference between the runs is the arithmetic. At REBOUND's default tolerance the wide format recovers four orders of magnitude of accuracy at once, ten at a tolerance of 1e-12, eighteen at 1e-16.

Going up to binary256 is a step that, for that integrator, changes nothing: at every step size a user would choose, binary256 is identical to binary128 to every digit, because a fifteenth-order method's own truncation error sits far above the binary128 floor. The one regime the study found for it is the outer solar system at ten-to-twenty-day steps, where it is worth one to six orders more. A negative result, measured and kept, is the most honest link a site can offer to its neighbour.

This site's own experimentBurrau's Pythagorean problem: the same steps at binary64 and binary128

Three bodies of mass 3, 4 and 5 at the corners of a 3-4-5 triangle, released from rest: a chaotic problem with close encounters. Three runs of REBOUND's IAS15 on an identical, prescribed step sequence, differing only in the arithmetic's width, and each of the two narrower ones differenced against the binary256 run on every step. The lines are the largest relative coordinate difference; the data is cft-rebound's own (results/horizon/pythagorean), not recomputed here.

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).