bposit: the Bounded Posit
A posit’s tapered precision is its strength: it spends bits on dynamic range only when a value needs them. At the extremes, though, the regime keeps growing until it has consumed every bit, so near maxpos and minpos a standard posit has no fraction bits at all. Its precision falls to zero. The variable-length regime also makes decode and encode hardware depend on the precision.
bposit is John Gustafson’s bounded posit (b-posit). It caps the regime at a maximum size rS. Every value then keeps a guaranteed number of fraction bits, the decoder’s critical path is nearly the same at every precision, and the quire is bounded: for fixed rS and eS it grows by only two bits per bit of precision. The price is a bounded dynamic range.
Sources:
- Closing the Gap Between Float and Posit Hardware Efficiency, arXiv 2603.01615
- John L. Gustafson, Every Bit Counts: Posit Computing
bposit<nbits, rs, es, bt>
| Parameter | Meaning |
|---|---|
nbits |
total bits, at most 64 |
rs |
maximum regime size, in bits (Gustafson’s rS) |
es |
exponent size, in bits (Gustafson’s eS); always present in full |
bt |
storage block type, default std::uint8_t |
Constraints, checked at compile time:
2 <= rs < nbits - 1nbits > 1 + rs + es: at least one fraction bit at every magnitudenbits <= 64rs * 2^es <= 2^28, so every scale, and the sum of two scales in a product, fits anint
Standard configurations, Gustafson’s rS = 6, eS = 5:
| alias | type | fraction bits | scale range | minpos .. maxpos |
|---|---|---|---|---|
bposit16 |
bposit<16, 6, 5, uint16_t> |
4 .. 8 | [-192, 191] | 1.69e-58 .. 6.08e57 |
bposit32 |
bposit<32, 6, 5, uint32_t> |
20 .. 24 | [-192, 191] | 1.59e-58 .. 6.28e57 |
bposit64 |
bposit<64, 6, 5, uint64_t> |
52 .. 56 | [-192, 191] | 1.59e-58 .. 6.28e57 |
Encoding
Section titled “Encoding”[ sign | regime: 2..rs bits | exponent: es bits | fraction: the rest ]A negative value is the two’s complement of its magnitude’s encoding, as for posits. Fields are read from the magnitude.
Regime. The regime is a run of identical bits that counts its terminating bit:
- A run that is shorter than
rsends with one opposite bit. The regime is then the run plus that bit. - A run that reaches
rsbits ends there, with no terminating bit.
So the regime field is 2 .. rs bits long. Its value is r = run - 1 for a run of ones and r = -run for a run of zeros. That gives r in [-rs, rs - 1]. A standard posit is the special case rs = nbits - 1.
Exponent. The exponent e is always the full es bits: the bounded regime never truncates it.
Fraction. The fraction f is the remaining nbits - 1 - (regime size) - es bits.
Value:
x = (-1)^sign * (1 + f) * 2^(r * 2^es + e)Derived quantities:
| formula | <16, 6, 5> |
|
|---|---|---|
| scale range | [-rs * 2^es, rs * 2^es - 1] |
[-192, 191] |
fewest fraction bits (F_min) |
nbits - 1 - rs - es |
4 |
| most fraction bits | nbits - 3 - es |
8 |
| maxpos | (2 - 2^-F_min) * 2^(rs * 2^es - 1) |
6.08e57 |
| minpos | (1 + 2^-F_min) * 2^(-rs * 2^es) |
1.69e-58 |
minpos is not a power of two. The pattern 0...01 carries the capped all-zeros regime, a zero exponent and a fraction of 2^-F_min. The exact power of two 2^(-rs * 2^es) would be the all-zero pattern, which is zero.
Special values. As for posits: zero is 0...0, and NaR is 10...0. There is no infinity and no negative zero.
Order. Encodings are monotonic. Read as two’s-complement integers, bit patterns order exactly as their values. Comparison is integer comparison, and ++ / -- step to the adjacent value.
Rounding and saturation
Section titled “Rounding and saturation”These follow the posit standard:
- Rounding: round to nearest, ties to the even encoding.
- Never to 0 or NaR: a nonzero real never rounds to 0, and a finite real never rounds to NaR.
- Clamping: a magnitude above maxpos becomes maxpos, and a nonzero magnitude below minpos becomes minpos. Signs are kept.
Range and precision profile
Section titled “Range and precision profile”| config | F_min |
max fraction | scale range | minpos | maxpos | decades |
|---|---|---|---|---|---|---|
<8,4,0> |
3 | 5 | [-4, 3] | 0.07031 | 15 | 2.3 |
<8,3,1> |
3 | 4 | [-6, 5] | 0.01758 | 60 | 3.5 |
<12,4,2> |
5 | 7 | [-16, 15] | 1.574e-05 | 6.451e+04 | 9.6 |
<16,4,2> |
9 | 11 | [-16, 15] | 1.529e-05 | 6.547e+04 | 9.6 |
<16,6,5> |
4 | 8 | [-192, 191] | 1.693e-58 | 6.081e+57 | 115.6 |
<32,6,5> |
20 | 24 | [-192, 191] | 1.593e-58 | 6.277e+57 | 115.6 |
<64,6,5> |
52 | 56 | [-192, 191] | 1.593e-58 | 6.277e+57 | 115.6 |
With rS = 6, eS = 5 the range is the same for every nbits > 12. Extra bits buy only precision. For comparison, a standard posit<32, 2> spans about 1e-36 .. 1e36, but falls to zero fraction bits at the ends.
Choosing a b-posit for DSP and FFT pipelines
Section titled “Choosing a b-posit for DSP and FFT pipelines”The b-posit paper (arXiv 2603.01615) singles out signal processing as a workload where a smaller eS suffices: the unused dynamic range is traded for guaranteed fraction bits. The precision profile shows how much. It plots the decimals of accuracy, -log10(ulp / (2|x|)), against magnitude across the whole encoding (#1636, universal/utility/precision_profile.hpp).
The DSP questions read straight off the curves:
- The signal band. Samples are normalized to [-1, 1), so the precision just below 1.0 sets the quantization noise floor, at about 6.02 dB of SQNR per bit.
- FFT growth. An N-point FFT grows magnitudes by up to log2(N) bits, so the type needs range above 1.0. Without it, the pipeline must rescale at every stage.
- The floor. Small coefficients and tail energy, around 2^-15 (-90 dBFS), should not fall off a cliff.
Measured by applications/mixed-precision/dsp/precision_profiles.cpp. “Floor” is the fewest fraction bits anywhere in the type’s range.
| 16-bit type | range (log2) | decimals in [0.5, 1) | at 2^-15 | at 2^10 (N = 1024) | floor (bits) |
|---|---|---|---|---|---|
int16 |
0 .. 15 | 0 | 0 | 3.31 | 0 |
Q15, fixpnt<16,15> |
-15 .. 0 | 4.52 | 0.30 | 0 | 0 |
fp16, cfloat<16,5> |
-24 .. 16 | 3.31 | 3.01 | 3.31 | 0 (subnormals) |
lns<16,10> |
-16 .. 16 | 3.47 | 3.47 | 3.47 | 10.5 |
bposit<16,6,5> |
-192 .. 192 | 2.71 | 2.71 | 2.71 | 4 |
bposit<16,5,2> |
-20 .. 20 | 3.61 | 2.71 | 3.01 | 8 |
| 32-bit type | range (log2) | decimals in [0.5, 1) | at 2^-15 | at 2^10 | floor (bits) |
|---|---|---|---|---|---|
int32 |
0 .. 31 | 0 | 0 | 3.31 | 0 |
Q31, fixpnt<32,31> |
-31 .. 0 | 9.33 | 5.12 | 0 | 0 |
float |
-149 .. 128 | 7.22 | 7.22 | 7.22 | 0 (subnormals) |
lns<32,23> |
-128 .. 128 | 7.38 | 7.38 | 7.38 | 23.5 |
bposit<32,6,5> |
-192 .. 192 | 7.53 | 7.53 | 7.53 | 20 |
bposit<32,5,2> |
-20 .. 20 | 8.43 | 7.53 | 7.83 | 24 |
What the curves say:
- Fixed-point is the most precise inside the signal band, but it has no headroom: Q15 has 0 decimals at 1.0, so every FFT stage must rescale. Below the band it falls off a cliff: one bit left at 2^-15.
- The standard
bposit<16,6,5>spends its bits on a 2^+-192 range that a DSP pipeline never uses. It trails fp16 in the signal band. - A b-posit sized to the region of interest [2^-15, 2^12] does much better. The tightest fit,
bposit<16,4,2>, spans 2^+-16 and puts 92% of its encodings in the region, against 21% forbposit<16,6,5>. It keeps at least 3.01 decimals across the region and never drops below 9 fraction bits. Its precision is tapered: it is one bit ahead of fp16 from 2^-4 to 2^4 (3.61 against 3.31 decimals in [0.5, 1)), level with it out to 2^+-8, and one bit behind beyond that.bposit<16,5,2>gives four more binades of headroom (to 2^20) for one bit of floor. At 32 bits,bposit<32,4,2>beats float across the whole region (8.43 against 7.22 decimals in [0.5, 1)) with a 25-bit floor. - The range must still fit the signal.
bposit<16,3,1>keeps 3.91 decimals in the band but spans only 2^+-6, leaving 0 decimals at 2^-15 and at 2^10. - An lns sized to the same range (
lns<16,10>) is flat at 3.47 decimals, between fp16 and the DSP-sized b-posit.
To plot the profiles:
dsp_precision_profiles out/python3 tools/notebooks/plot_precision_profiles.py out/Q15.csv out/fp16.csv out/lns_16_10_.csv out/bposit_16_6_5_.csv out/bposit_16_5_2_.csv --dsp -o profiles16.png--dsp shades the signal band, marks FFT growth for N = 256, 1024 and 4096, and adds an SQNR axis. The tutorial Decimals of accuracy tells the whole story, from the full-range picture to the fitted b-posit, with the command for every figure.
numeric_limits
Section titled “numeric_limits”| member | value |
|---|---|
min() |
minpos |
max() |
maxpos |
lowest() |
-maxpos |
epsilon() |
2^-(nbits - 3 - es), the gap above 1.0 |
digits |
nbits - 2 - es, the significand bits at 1.0 |
radix |
2 |
round_style |
round_to_nearest |
has_infinity |
false |
quiet_NaN() |
NaR |
min_exponent / max_exponent |
-rs * 2^es + 1 / rs * 2^es |
bposit does not have the TwoSum / TwoProduct property
Section titled “bposit does not have the TwoSum / TwoProduct property”Bounding the taper guarantees fraction bits, but it does not make the roundoff of an operation representable. So TwoSum and TwoProduct are not exact error-free transformations for bposit.
The 8-bit counterexample (#1251). In bposit<8, 4, 0>, minpos is 9/128.
- TwoSum. 9/128 + 5/64 = 19/128. That is a tie between 9/64 (encoding 0x09) and 5/32 (0x0A), so it rounds to the even encoding, 5/32. The error, -1/128, is below minpos and not representable.
- TwoProduct. 9/128 * -15 = -135/128 rounds to -17/16. The error, 1/128, is not representable.
Exhaustive counts, over all pairs of nonzero operands whose exact result lies strictly between minpos and maxpos:
| config | TwoSum: unrepresentable error | TwoProduct: unrepresentable error |
|---|---|---|
<8, 4, 0> |
22832 of 61884 | 43788 of 57000 |
<8, 3, 1> |
11720 of 62924 | 25036 of 53004 |
The standard configuration fails too. In bposit<16, 6, 5>:
- TwoSum fails for 2872 of the 4096 pairs among the 64 smallest values. For example, (1 + 1/16) 2^-192 + (1 + 1/8) 2^-192 leaves (1/16) 2^-192, below minpos = (17/16) 2^-192.
- TwoProduct’s error is unrepresentable for about 0.2% of random pairs at ordinary magnitudes, and about 12% across the full range.
Exact accumulation in bposit therefore comes from the quire (below), which always works; compensated summation does not. bposit provides no exact twosum / twoprod.
Quire: exact dot products
Section titled “Quire: exact dot products”quire<bposit<...>> is the generalized quire, sized by quire_traits<bposit<nbits, rs, es, bt>>. Every product of two bposits lands in it exactly; fdp(x, y) accumulates quire_mul(x[i], y[i]) and rounds the sum once with quire_resolve, through bposit’s own encoder, so the result saturates to +/-minpos or +/-maxpos like any other bposit result, never to 0 or NaR.
The layout puts the smallest product bit at bit 0 and maxpos^2 below the top:
| formula | <16,6,5> |
<32,6,5> |
<64,6,5> |
|
|---|---|---|---|---|
| smallest product bit | 2^-(2 (rs 2^es + F_min)) |
2^-392 | 2^-424 | 2^-488 |
| radix point | 2 (rs 2^es + F_min) |
392 | 424 | 488 |
| upper range | 2 rs 2^es |
384 | 384 | 384 |
| range | 4 rs 2^es + 2 F_min |
776 | 808 | 872 |
| with the default 30 carry bits | range + 30 |
806 | 838 | 902 |
The quire size depends on n. A b-posit’s smallest values still carry F_min fraction bits, so products of tiny values reach 2 F_min bits below minpos^2. Sizing from minpos^2 alone, as the often-quoted “800 bits for any n > 12” does, matches the exact size only at n = 16 (776 bits, plus a 23-bit carry guard and the sign). Anchoring the quire at minpos^2 drops the lowest 2 F_min bits of products of tiny values: 8 at n = 16, 104 at n = 64. This is the trap #1202 fixed for cfloat. The ranges above were confirmed by brute force over all products of the small configurations, and static/tapered/bposit/arithmetic/fdp.cpp checks a dot product whose exact value lives only in those low bits.
std::vector<bposit32> x = ..., y = ...;bposit32 d = fdp(x, y); // exact sum of products, rounded once
quire<bposit32> q; // or accumulate by handfor (std::size_t i = 0; i < x.size(); ++i) q += quire_mul(x[i], y[i]);bposit32 s = quire_resolve(q);Fused multiply-add
Section titled “Fused multiply-add”fma(a, b, c) is the shortest quire sum: a*b and c accumulated exactly, rounded once. It follows the std::fma contract, so has_fma_v<bposit<...>> is true and the ADL two-step using std::fma; fma(a, b, c) in a generic kernel finds it. A NaR operand gives NaR; a result that cancels to exactly zero is zero; a nonzero result below minpos or above maxpos saturates like any other bposit result. static/tapered/bposit/arithmetic/fma.cpp checks it against the exact value over every (a, b) pair of the 6- and 8-bit configurations, including c = -(a*b rounded), where the result is the product’s rounding error and is often below minpos.
Math library
Section titled “Math library”bposit.hpp includes bposit/mathlib.hpp, so sin(x), sqrt(x) and the rest are found by ADL on any bposit<nbits, rs, es, bt>, and generic code (an FFT that builds its twiddles with cos and sin in T, a window function, an NCO) compiles for b-posits.
| header | functions | rounding |
|---|---|---|
classify.hpp |
fpclassify, isfinite, isinf, isnan, isnormal, signbit |
exact |
next.hpp, minmax.hpp |
nextafter, nexttoward, min, max; fabs, copysign in mathlib.hpp |
exact |
truncate.hpp, fractional.hpp |
floor, ceil, trunc, round, fmod, remainder, frac |
exact, or correctly rounded |
sqrt.hpp, hypot.hpp |
sqrt, cbrt, hypot (two and three arguments) |
correctly rounded |
exponent.hpp, logarithm.hpp, pow.hpp |
exp, exp2, exp10, expm1, log, log2, log10, log1p, pow |
correctly rounded |
trigonometry.hpp, hyperbolic.hpp |
sin, cos, tan, asin, acos, atan, atan2, sinh, cosh, tanh, asinh, acosh, atanh |
correctly rounded |
error_and_gamma.hpp |
erf, erfc, tgamma, lgamma |
correctly rounded |
complex.hpp |
sw::universal::complex<bposit>: arithmetic, abs, arg, norm, exp, log, sqrt, pow, trigonometric |
through std::complex<double> |
Correct rounding
Section titled “Correct rounding”The posit standard requires every function to be correctly rounded for every input, because bitwise reproducibility depends on it: the result is the true value rounded once, to nearest with ties to the even encoding. The b-posit math library meets that with Ziv’s strategy (math/correctly_rounded.hpp):
- Fast path. The function is evaluated in double through libm, whose result is within a few ulps of the true value (
BPOSIT_MATH_LIBM_ULPS, default 4; glibc documents 1 to 2 for these functions). If both ends of that interval round to the same b-posit, so does the true value. This decides nearly every input of a 16- or 32-bit b-posit, at about twice the cost of a plain libm call. - Quad-double. Otherwise the function is evaluated in
qd, about 212 bits, from the exact argument, with an error far below 2^-170, and the same test is applied. - Exact midpoints. If even that interval straddles a rounding boundary, the true value is on it, and it rounds to the even neighbor.
powreaches these at ordinary arguments:exp10(4) = 10000is a midpoint ofbposit<16,6,5>.atan2(y, x)with a tinyy / xis the one case where a transcendental value comes closer to a midpoint than 2^-170 without being on it, and it is resolved exactly.
The quad-double kernels avoid the cancellations of the textbook formulas: log near 1 goes through log1p of the exact x - 1, asin and acos through atan2 of exact differences, and sin, cos and tan reduce their argument exactly with Payne and Hanek’s method, from 1280 bits of 2/pi, so sin(maxpos) is correctly rounded too. The truncations, fmod and remainder are computed exactly in integers from the encodings.
The fast path needs the argument to convert to double exactly (fbits + 1 <= 53), which holds for every 16- and 32-bit configuration. bposit<64, 6, 5> takes the quad-double path every time, at some 5 to 15 microseconds per call. The quad-double engine needs the range inside double’s: |scale| <= 600, which covers every standard and DSP-fitted configuration; a configuration beyond it falls back to the evaluation in double, which is not correctly rounded.
static/tapered/bposit/math/correct_rounding.cpp checks every result for equality with an oracle that shares no code with the library: long double libm first, and ereal<8> with exact midpoint comparisons when that is ambiguous. Every encoding of bposit<16,4,2>, <16,5,2> and <16,6,5> is checked through 26 functions, by both the default path and the quad-double engine alone, and the 32- and 64-bit configurations and the two-argument functions are sampled.
erf, erfc, tgamma and lgamma use quad-double’s error and gamma functions. libm’s erfc and tgamma get wider bounds, 8 and 16 ulps, and lgamma’s is counted in ulps of max(|lgamma|, 1), since libm’s lgamma is only accurate in absolute terms near its zeros. One limit remains there: near the negative zeros of lgamma (x near -2.457, -2.747, …) the reflection formula is accurate to about 2^-200 absolute, which decides every 16- and 32-bit input, but a 64-bit argument within about 2^-30 of such a zero may round incorrectly.
complex<bposit> evaluates its functions through std::complex<double>, one rounding per component.
The posit standard’s promises
Section titled “The posit standard’s promises”- A finite result never becomes NaR.
exp(maxpos),sinh(maxpos),pow(2, maxpos)andtgamma(maxpos)saturate to maxpos. - A nonzero result never becomes 0.
exp(maxneg),erfc(maxpos)andpow(2, maxneg)saturate to minpos, with the result’s sign:tgamma(-200.5)is-minpos.
Poles and domain errors are NaR: log(0), log(-1), sqrt(-1), atanh(1), tgamma(0), tgamma(-1), pow(0, -1), and fmod(x, 0). NaR in any argument gives NaR, for min and max too. There is no infinity, so isinf is always false.
Reference encoding: bposit<8, 4, 0>
Section titled “Reference encoding: bposit<8, 4, 0>”All 128 non-negative encodings. A negative value is the two’s complement of the matching positive one, and 0x80 is NaR. The fraction field is never empty. Patterns 0x01 .. 0x07 (r = -4) and 0x78 .. 0x7F (r = 3) use the capped 4-bit regime, which has no terminating bit.
| pattern | bits after sign | regime | r | fraction | fraction bits | value |
|---|---|---|---|---|---|---|
| 0x00 | 0000000 | (zero) | 0 | |||
| 0x01 | 0000001 | 0000 | -4 | 001 | 3 | 9/128 |
| 0x02 | 0000010 | 0000 | -4 | 010 | 3 | 5/64 |
| 0x03 | 0000011 | 0000 | -4 | 011 | 3 | 11/128 |
| 0x04 | 0000100 | 0000 | -4 | 100 | 3 | 3/32 |
| 0x05 | 0000101 | 0000 | -4 | 101 | 3 | 13/128 |
| 0x06 | 0000110 | 0000 | -4 | 110 | 3 | 7/64 |
| 0x07 | 0000111 | 0000 | -4 | 111 | 3 | 15/128 |
| 0x08 | 0001000 | 0001 | -3 | 000 | 3 | 1/8 |
| 0x09 | 0001001 | 0001 | -3 | 001 | 3 | 9/64 |
| 0x0A | 0001010 | 0001 | -3 | 010 | 3 | 5/32 |
| 0x0B | 0001011 | 0001 | -3 | 011 | 3 | 11/64 |
| 0x0C | 0001100 | 0001 | -3 | 100 | 3 | 3/16 |
| 0x0D | 0001101 | 0001 | -3 | 101 | 3 | 13/64 |
| 0x0E | 0001110 | 0001 | -3 | 110 | 3 | 7/32 |
| 0x0F | 0001111 | 0001 | -3 | 111 | 3 | 15/64 |
| 0x10 | 0010000 | 001 | -2 | 0000 | 4 | 1/4 |
| 0x11 | 0010001 | 001 | -2 | 0001 | 4 | 17/64 |
| 0x12 | 0010010 | 001 | -2 | 0010 | 4 | 9/32 |
| 0x13 | 0010011 | 001 | -2 | 0011 | 4 | 19/64 |
| 0x14 | 0010100 | 001 | -2 | 0100 | 4 | 5/16 |
| 0x15 | 0010101 | 001 | -2 | 0101 | 4 | 21/64 |
| 0x16 | 0010110 | 001 | -2 | 0110 | 4 | 11/32 |
| 0x17 | 0010111 | 001 | -2 | 0111 | 4 | 23/64 |
| 0x18 | 0011000 | 001 | -2 | 1000 | 4 | 3/8 |
| 0x19 | 0011001 | 001 | -2 | 1001 | 4 | 25/64 |
| 0x1A | 0011010 | 001 | -2 | 1010 | 4 | 13/32 |
| 0x1B | 0011011 | 001 | -2 | 1011 | 4 | 27/64 |
| 0x1C | 0011100 | 001 | -2 | 1100 | 4 | 7/16 |
| 0x1D | 0011101 | 001 | -2 | 1101 | 4 | 29/64 |
| 0x1E | 0011110 | 001 | -2 | 1110 | 4 | 15/32 |
| 0x1F | 0011111 | 001 | -2 | 1111 | 4 | 31/64 |
| 0x20 | 0100000 | 01 | -1 | 00000 | 5 | 1/2 |
| 0x21 | 0100001 | 01 | -1 | 00001 | 5 | 33/64 |
| 0x22 | 0100010 | 01 | -1 | 00010 | 5 | 17/32 |
| 0x23 | 0100011 | 01 | -1 | 00011 | 5 | 35/64 |
| 0x24 | 0100100 | 01 | -1 | 00100 | 5 | 9/16 |
| 0x25 | 0100101 | 01 | -1 | 00101 | 5 | 37/64 |
| 0x26 | 0100110 | 01 | -1 | 00110 | 5 | 19/32 |
| 0x27 | 0100111 | 01 | -1 | 00111 | 5 | 39/64 |
| 0x28 | 0101000 | 01 | -1 | 01000 | 5 | 5/8 |
| 0x29 | 0101001 | 01 | -1 | 01001 | 5 | 41/64 |
| 0x2A | 0101010 | 01 | -1 | 01010 | 5 | 21/32 |
| 0x2B | 0101011 | 01 | -1 | 01011 | 5 | 43/64 |
| 0x2C | 0101100 | 01 | -1 | 01100 | 5 | 11/16 |
| 0x2D | 0101101 | 01 | -1 | 01101 | 5 | 45/64 |
| 0x2E | 0101110 | 01 | -1 | 01110 | 5 | 23/32 |
| 0x2F | 0101111 | 01 | -1 | 01111 | 5 | 47/64 |
| 0x30 | 0110000 | 01 | -1 | 10000 | 5 | 3/4 |
| 0x31 | 0110001 | 01 | -1 | 10001 | 5 | 49/64 |
| 0x32 | 0110010 | 01 | -1 | 10010 | 5 | 25/32 |
| 0x33 | 0110011 | 01 | -1 | 10011 | 5 | 51/64 |
| 0x34 | 0110100 | 01 | -1 | 10100 | 5 | 13/16 |
| 0x35 | 0110101 | 01 | -1 | 10101 | 5 | 53/64 |
| 0x36 | 0110110 | 01 | -1 | 10110 | 5 | 27/32 |
| 0x37 | 0110111 | 01 | -1 | 10111 | 5 | 55/64 |
| 0x38 | 0111000 | 01 | -1 | 11000 | 5 | 7/8 |
| 0x39 | 0111001 | 01 | -1 | 11001 | 5 | 57/64 |
| 0x3A | 0111010 | 01 | -1 | 11010 | 5 | 29/32 |
| 0x3B | 0111011 | 01 | -1 | 11011 | 5 | 59/64 |
| 0x3C | 0111100 | 01 | -1 | 11100 | 5 | 15/16 |
| 0x3D | 0111101 | 01 | -1 | 11101 | 5 | 61/64 |
| 0x3E | 0111110 | 01 | -1 | 11110 | 5 | 31/32 |
| 0x3F | 0111111 | 01 | -1 | 11111 | 5 | 63/64 |
| 0x40 | 1000000 | 10 | 0 | 00000 | 5 | 1 |
| 0x41 | 1000001 | 10 | 0 | 00001 | 5 | 33/32 |
| 0x42 | 1000010 | 10 | 0 | 00010 | 5 | 17/16 |
| 0x43 | 1000011 | 10 | 0 | 00011 | 5 | 35/32 |
| 0x44 | 1000100 | 10 | 0 | 00100 | 5 | 9/8 |
| 0x45 | 1000101 | 10 | 0 | 00101 | 5 | 37/32 |
| 0x46 | 1000110 | 10 | 0 | 00110 | 5 | 19/16 |
| 0x47 | 1000111 | 10 | 0 | 00111 | 5 | 39/32 |
| 0x48 | 1001000 | 10 | 0 | 01000 | 5 | 5/4 |
| 0x49 | 1001001 | 10 | 0 | 01001 | 5 | 41/32 |
| 0x4A | 1001010 | 10 | 0 | 01010 | 5 | 21/16 |
| 0x4B | 1001011 | 10 | 0 | 01011 | 5 | 43/32 |
| 0x4C | 1001100 | 10 | 0 | 01100 | 5 | 11/8 |
| 0x4D | 1001101 | 10 | 0 | 01101 | 5 | 45/32 |
| 0x4E | 1001110 | 10 | 0 | 01110 | 5 | 23/16 |
| 0x4F | 1001111 | 10 | 0 | 01111 | 5 | 47/32 |
| 0x50 | 1010000 | 10 | 0 | 10000 | 5 | 3/2 |
| 0x51 | 1010001 | 10 | 0 | 10001 | 5 | 49/32 |
| 0x52 | 1010010 | 10 | 0 | 10010 | 5 | 25/16 |
| 0x53 | 1010011 | 10 | 0 | 10011 | 5 | 51/32 |
| 0x54 | 1010100 | 10 | 0 | 10100 | 5 | 13/8 |
| 0x55 | 1010101 | 10 | 0 | 10101 | 5 | 53/32 |
| 0x56 | 1010110 | 10 | 0 | 10110 | 5 | 27/16 |
| 0x57 | 1010111 | 10 | 0 | 10111 | 5 | 55/32 |
| 0x58 | 1011000 | 10 | 0 | 11000 | 5 | 7/4 |
| 0x59 | 1011001 | 10 | 0 | 11001 | 5 | 57/32 |
| 0x5A | 1011010 | 10 | 0 | 11010 | 5 | 29/16 |
| 0x5B | 1011011 | 10 | 0 | 11011 | 5 | 59/32 |
| 0x5C | 1011100 | 10 | 0 | 11100 | 5 | 15/8 |
| 0x5D | 1011101 | 10 | 0 | 11101 | 5 | 61/32 |
| 0x5E | 1011110 | 10 | 0 | 11110 | 5 | 31/16 |
| 0x5F | 1011111 | 10 | 0 | 11111 | 5 | 63/32 |
| 0x60 | 1100000 | 110 | 1 | 0000 | 4 | 2 |
| 0x61 | 1100001 | 110 | 1 | 0001 | 4 | 17/8 |
| 0x62 | 1100010 | 110 | 1 | 0010 | 4 | 9/4 |
| 0x63 | 1100011 | 110 | 1 | 0011 | 4 | 19/8 |
| 0x64 | 1100100 | 110 | 1 | 0100 | 4 | 5/2 |
| 0x65 | 1100101 | 110 | 1 | 0101 | 4 | 21/8 |
| 0x66 | 1100110 | 110 | 1 | 0110 | 4 | 11/4 |
| 0x67 | 1100111 | 110 | 1 | 0111 | 4 | 23/8 |
| 0x68 | 1101000 | 110 | 1 | 1000 | 4 | 3 |
| 0x69 | 1101001 | 110 | 1 | 1001 | 4 | 25/8 |
| 0x6A | 1101010 | 110 | 1 | 1010 | 4 | 13/4 |
| 0x6B | 1101011 | 110 | 1 | 1011 | 4 | 27/8 |
| 0x6C | 1101100 | 110 | 1 | 1100 | 4 | 7/2 |
| 0x6D | 1101101 | 110 | 1 | 1101 | 4 | 29/8 |
| 0x6E | 1101110 | 110 | 1 | 1110 | 4 | 15/4 |
| 0x6F | 1101111 | 110 | 1 | 1111 | 4 | 31/8 |
| 0x70 | 1110000 | 1110 | 2 | 000 | 3 | 4 |
| 0x71 | 1110001 | 1110 | 2 | 001 | 3 | 9/2 |
| 0x72 | 1110010 | 1110 | 2 | 010 | 3 | 5 |
| 0x73 | 1110011 | 1110 | 2 | 011 | 3 | 11/2 |
| 0x74 | 1110100 | 1110 | 2 | 100 | 3 | 6 |
| 0x75 | 1110101 | 1110 | 2 | 101 | 3 | 13/2 |
| 0x76 | 1110110 | 1110 | 2 | 110 | 3 | 7 |
| 0x77 | 1110111 | 1110 | 2 | 111 | 3 | 15/2 |
| 0x78 | 1111000 | 1111 | 3 | 000 | 3 | 8 |
| 0x79 | 1111001 | 1111 | 3 | 001 | 3 | 9 |
| 0x7A | 1111010 | 1111 | 3 | 010 | 3 | 10 |
| 0x7B | 1111011 | 1111 | 3 | 011 | 3 | 11 |
| 0x7C | 1111100 | 1111 | 3 | 100 | 3 | 12 |
| 0x7D | 1111101 | 1111 | 3 | 101 | 3 | 13 |
| 0x7E | 1111110 | 1111 | 3 | 110 | 3 | 14 |
| 0x7F | 1111111 | 1111 | 3 | 111 | 3 | 15 |
How to use it
Section titled “How to use it”#include <universal/number/bposit/bposit.hpp>using namespace sw::universal;
bposit32 a(3.0), b(7.0);bposit32 c = a / b; // round to nearest, ties to evenstd::cout << c << ' ' << to_binary(c) << '\n';
using Small = bposit<8, 4, 0>;Small tiny(1.0e-9); // saturates to minpos, 9/128: never zero
bposit<16, 4, 2> t(0.5);auto s = sin(t), e = exp(t); // the math library, found by ADLcomplex<bposit<16, 4, 2>> z(t, t);auto w = exp(z) * z; // complex arithmetic and functions