| Floating-pointformats |
|---|
| IEEE 754 |
|
| Other |
| Alternatives |
| Tapered floating point |
| Computer architecture bit widths |
|---|
| Bit |
| Application |
| Binary floating-pointprecision |
| Decimal floating-pointprecision |
Incomputing,quadruple precision (orquad precision) is a binaryfloating-point–basedcomputer number format that occupies 16 bytes (128 bits) with precision at least twice the 53-bitdouble precision.
This 128-bit quadruple precision is designed for applications needing results in higher than double precision,[1] and as a primary function, to allow computing double precision results more reliably and accurately by minimising overflow andround-off errors in intermediate calculations and scratch variables.William Kahan, primary architect of the original IEEE 754 floating-point standard noted, "For now the10-byte Extended format is a tolerable compromise between the value of extra-precise arithmetic and the price of implementing it to run fast; very soon two more bytes of precision will become tolerable, and ultimately a 16-byte format ... That kind of gradual evolution towards wider precision was already in view whenIEEE Standard 754 for Floating-Point Arithmetic was framed."[2]
InIEEE 754-2008 the 128-bit base-2 format is officially referred to asbinary128.
The IEEE 754 standard specifies abinary128 as having:
The sign bit determines the sign of the number (including when this number is zero, which issigned). "1" stands for negative.
This gives from 33 to 36 significant decimal digits precision. If a decimal string with at most 33 significant digits is converted to the IEEE 754 quadruple-precision format, giving a normal number, and then converted back to a decimal string with the same number of digits, the final result should match the original string. If an IEEE 754 quadruple-precision number is converted to a decimal string with at least 36 significant digits, and then converted back to quadruple-precision representation, the final result must match the original number.[3]
The format is written with an implicit lead bit with value 1 unless the exponent is stored with all zeros (used to encodesubnormal numbers and zeros). Thus only 112 bits of thesignificand appear in the memory format, but the total precision is 113 bits (approximately 34 decimal digits:log10(2113) ≈ 34.016) for normal values; subnormals have gracefully degrading precision down to 1 bit for the smallest non-zero value. The bits are laid out as:
The quadruple-precision binary floating-point exponent is encoded using anoffset binary representation, with the zero offset being 16383; this is also known as exponent bias in the IEEE 754 standard.
Thus, as defined by the offset binary representation, in order to get the true exponent, the offset of 16383 has to be subtracted from the stored exponent.
The stored exponents 000016 and 7FFF16 are interpreted specially.
| Exponent | Significand zero | Significand non-zero | Equation |
|---|---|---|---|
| 000016 | 0,−0 | subnormal numbers | (−1)signbit × 2−16382 × 0.significandbits2 |
| 000116, ..., 7FFE16 | normalized value | (−1)signbit × 2exponentbits2 − 16383 × 1.significandbits2 | |
| 7FFF16 | ±∞ | NaN (quiet, signaling) | |
The minimum strictly positive (subnormal) value is 2−16494 ≈ 10−4965 and has a precision of only one bit. The minimum positive normal value is 2−16382 ≈3.3621 × 10−4932 and has a precision of 113 bits, i.e. ±2−16494 as well. The maximum representable value is216384 − 216271 ≈1.1897 × 104932.
These examples are given in bitrepresentation, inhexadecimal, of the floating-point value. This includes the sign, (biased) exponent, and significand.
0000 0000 0000 0000 0000 0000 0000 000116 = 2−16382 × 2−112 = 2−16494 0000 ffff ffff ffff ffff ffff ffff ffff16 = 2−16382 × (1 − 2−112) 0001 0000 0000 0000 0000 0000 0000 000016 = 2−16382 7ffe ffff ffff ffff ffff ffff ffff ffff16 = 216383 × (2 − 2−112) 3ffe ffff ffff ffff ffff ffff ffff ffff16 = 1 − 2−113 3fff 0000 0000 0000 0000 0000 0000 000016 = 1 (one) 3fff 0000 0000 0000 0000 0000 0000 000116 = 1 + 2−112 4000 0000 0000 0000 0000 0000 0000 000016 = 2 0000 0000 0000 0000 0000 0000 0000 000016 = 0 7fff 0000 0000 0000 0000 0000 0000 000016 = infinity 3ffd 5555 5555 5555 5555 5555 5555 555516 ≈ 0.3333333333333333333333333333333333173 4000 921f b544 42d1 8469 898c c517 01b816 ≈ 3.1415926535897932384626433832795027975 4008 74d9 9564 5aa0 0c11 d0cc 9770 5e5b16 ≈ 745.69987158227021999999999999999997147 |
By default, 1/3 rounds down likedouble precision, because of the odd number of bits in the significand. Thus, the bits beyond the rounding point are0101... which is less than 1/2 of aunit in the last place.
A common software technique to implement nearly quadruple precision usingpairs ofdouble-precision values is sometimes calleddouble-double arithmetic.[4][5][6] Using pairs of IEEE double-precision values with 53-bit significands, double-double arithmetic provides operations on numbers with significands of at least[4]2 × 53 = 106 bits (actually 107 bits[7] except for some of the largest values, due to the limited exponent range), only slightly less precise than the 113-bit significand of IEEE binary128 quadruple precision. The range of a double-double remains essentially the same as the double-precision format because the exponent has still 11 bits,[4] significantly lower than the 15-bit exponent of IEEE quadruple precision (a range of1.8 × 10308 for double-double versus1.2 × 104932 for binary128).
In particular, a double-double/quadruple-precision valueq in the double-double technique is represented implicitly as a sumq =x +y of two double-precision valuesx andy, each of which supplies half ofq's significand.[5] That is, the pair(x,y) is stored in place ofq, and operations onq values(+, −, ×, ...) are transformed into equivalent (but more complicated) operations on thex andy values. Thus, arithmetic in this technique reduces to a sequence of double-precision operations; since double-precision arithmetic is commonly implemented in hardware, double-double arithmetic is typically substantially faster than more generalarbitrary-precision arithmetic techniques.[4][5]
Note that double-double arithmetic has the following special characteristics:[8]
In addition to the double-double arithmetic, it is also possible to generate triple-double or quad-double arithmetic if higher precision is required without any higher precision floating-point library. They are represented as a sum of three (or four) double-precision values respectively. They can represent operations with at least 159/161 and 212/215 bits respectively. A natural extension to an arbitrary number of terms (though limited by the exponent range) is calledfloating-point expansions.
A similar technique can be used to produce adouble-quad arithmetic, which is represented as a sum of two quadruple-precision values. They can represent operations with at least 226 (or 227) bits.[9]
Quadruple precision is often implemented in software by a variety of techniques (such as the double-double technique above, although that technique does not implement IEEE quadruple precision), since direct hardware support for quadruple precision is, as of 2016[update], less common (see "Hardware support" below). One can use generalarbitrary-precision arithmetic libraries to obtain quadruple (or higher) precision, but specialized quadruple-precision implementations may achieve higher performance.
A separate question is the extent to which quadruple-precision types are directly incorporated into computerprogramming languages.
Quadruple precision is specified inFortran by thereal(real128) (moduleiso_fortran_env from Fortran 2008 must be used, the constantreal128 is equal to 16 on most processors), or asreal(selected_real_kind(33, 4931)), or in a non-standard way asREAL*16. (Quadruple-precisionREAL*16 is supported by theIntel Fortran Compiler[10] and by theGNU Fortran compiler[11] onx86,x86-64, andItanium architectures, for example.)
For theC programming language, ISO/IEC TS 18661-3 (floating-point extensions for C, interchange and extended types) specifies_Float128 as the type implementing the IEEE 754 quadruple-precision format (binary128).[12] Alternatively, inC/C++ with a few systems and compilers, quadruple precision may be specified by thelong double type, but this is not required by the language (which only requireslong double to be at least as precise asdouble), nor is it common.
As ofC++23, the C++ language defines a<stdfloat> header that contains fixed-width floating-point types. Implementations of these are optional, but if supported,std::float128_t corresponds to quadruple precision.
On x86 and x86-64, the most common C/C++ compilers implementlong double as either 80-bitextended precision (e.g. theGNU C Compiler gcc[13] and theIntel C++ Compiler with a/Qlong‑double switch[14]) or simply as being synonymous with double precision (e.g.Microsoft Visual C++[15]), rather than as quadruple precision. The procedure call standard for theARM 64-bit architecture (AArch64) specifies thatlong double corresponds to the IEEE 754 quadruple-precision format.[16] On a few other architectures, some C/C++ compilers implementlong double as quadruple precision, e.g. gcc onPowerPC (as double-double[17][18][19]) andSPARC,[20] or theSun Studio compilers on SPARC.[21] Even iflong double is not quadruple precision, however, some C/C++ compilers provide a nonstandard quadruple-precision type as an extension. For example, gcc provides a quadruple-precision type called__float128 for x86, x86-64 andItanium CPUs,[22] and onPowerPC as IEEE 128-bit floating-point using the -mfloat128-hardware or -mfloat128 options;[23] and some versions of Intel's C/C++ compiler for x86 and x86-64 supply a nonstandard quadruple-precision type called_Quad.[24]
Zig provides support for it with itsf128 type.[25]
Google's work-in-progress languageCarbon provides support for it with the type calledf128.[26]
As of 2024,Rust is currently working on adding a newf128 type for IEEE quadruple-precision 128-bit floats.[27]
__float128 and__complex128 operations.__float128 and_Quad types, and includes a custom implementation of the standard math library.[28]IEEE quadruple precision was added to theIBM System/390 G5 in 1998,[32] and is supported in hardware in subsequentz/Architecture processors.[33][34] The IBMPOWER9 CPU (Power ISA 3.0) has native 128-bit hardware support.[23]
Native support of IEEE 128-bit floats is defined inPA-RISC 1.0,[35] and inSPARC V8[36] and V9[37] architectures (e.g. there are 16 quad-precision registers %q0, %q4, ...), but no SPARC CPU implements quad-precision operations in hardware as of 2004[update].[38]
Non-IEEE extended-precision (128 bits of storage, 1 sign bit, 7 exponent bits, 112 fraction bits, 8 bits unused) was added to theIBM System/370 series (1970s–1980s) and was available on someSystem/360 models in the 1960s (System/360-85,[39] -195, and others by special request or simulated by OS software).
TheSiemens 7.700 and 7.500 series mainframes and their successors support the same floating-point formats and instructions as the IBM System/360 and System/370.
TheVAX processor implemented non-IEEE quadruple-precision floating point as its "H Floating-point" format. It had one sign bit, a 15-bit exponent and 112-fraction bits, however the layout in memory was significantly different from IEEE quadruple precision and the exponent bias also differed. Only a few of the earliest VAX processors implemented H Floating-point instructions in hardware, all the others emulated H Floating-point in software.
TheNEC Vector Engine architecture supports adding, subtracting, multiplying and comparing 128-bit binary IEEE 754 quadruple-precision numbers.[40] Two neighboring 64-bit registers are used. Quadruple-precision arithmetic is not supported in the vector register.[41]
TheRISC-V architecture specifies a "Q" (quad-precision) extension for 128-bit binary IEEE 754-2008 floating-point arithmetic.[42] The "L" extension (not yet certified) will specify 64-bit and 128-bit decimal floating point.[43]
Quadruple-precision (128-bit) hardware implementation should not be confused with "128-bit FPUs" that implementSIMD instructions, such asStreaming SIMD Extensions orAltiVec, which refers to 128-bitvectors of four 32-bit single-precision or two 64-bit double-precision values that are operated on simultaneously.
SPARC is an instruction set architecture (ISA) with 32-bit integer and 32-, 64-, and 128-bit IEEE Standard 754 floating-point as its principal data types.
Floating-point: The architecture provides an IEEE 754-compatible floating-point instruction set, operating on a separate register file that provides 32 single-precision (32-bit), 32 double-precision (64-bit), 16 quad-precision (128-bit) registers, or a mixture thereof.
There are four situations, however, when the hardware will not successfully complete a floating-point instruction: ... The instruction is not implemented by the hardware (such as ... quad-precision instructions on any SPARC FPU).