35+ Number Systems
Integers, fixed-point, classic floats, posits, logarithmic, interval, adaptive-precision, AI quantization formats, and more.
35+ Number Systems
Integers, fixed-point, classic floats, posits, logarithmic, interval, adaptive-precision, AI quantization formats, and more.
IEEE-754 Out of the Box
half, single, duble, quad, octo – or fp16, fp32, fp64,
fp128, fp256. The standard formats, already spelled for you.
Header-Only
No external dependencies. Just #include and go. Pure C++20 templates.
Plug-in Replacement
Template your algorithms once, switch arithmetic types freely with zero code changes.
Comprehensive Testing
Exhaustive regression suites for every type. CI on GCC, Clang, and MSVC.
#include <iostream>#include <universal/number/cfloat/cfloat.hpp>
template<typename Real>Real MyKernel(const Real& a, const Real& b) { return a * b;}
int main() { using namespace sw::universal;
// half-precision IEEE-754 -- a predefined alias, same as fp16 half ha = sqrt(2); half hb = 3.14159265358979; half hc = MyKernel(ha, hb); std::cout << "Result: " << hc << '\n'; std::cout << "Bits : " << to_binary(hc) << " : " << color_print(hc) << '\n';
// single-precision IEEE-754 -- a predefined alias, same as fp32 single fa = sqrt(2); single fb = 3.14159265358979; single fc = MyKernel(fa, fb); std::cout << "Result: " << fc << std::endl; std::cout << "Bits : " << to_binary(fc) << " : " << color_print(fc) << std::endl;}To compile (assuming Universal is cloned to ./universal):
g++ -std=c++20 -I universal/include/sw -o kernel kernel.cppThe library requires C++20 and is header-only with no external dependencies.
The include path points to include/sw/ because headers use #include <universal/...> paths.
cfloat can express any floating-point format, but most developers want one of the six
the hardware already implements – and spelling those out by hand is where the mistakes
happen. They are predefined, under both their word names and their fpNN names:
| type | alias | bits | matches |
|---|---|---|---|
quarter |
fp8 |
8 | IEEE interchange rule at 8 bits |
half |
fp16 |
16 | IEEE-754 binary16 |
single |
fp32 |
32 | IEEE-754 binary32 |
duble |
fp64 |
64 | IEEE-754 binary64 |
quad |
fp128 |
128 | IEEE-754 binary128 |
octo |
fp256 |
256 | IEEE-754 binary256 |
single x = 1.0f; // exactly binary32 -- no template parameters to get wrongquad z = 1.0; // exactly binary128, on hardware that has never heard of itSee Standard IEEE types for the field widths, the two names that need a caveat, and how to choose between these and the faster extended-precision types.
| Category | Types |
|---|---|
| Integer & Fixed-Point | integer, fixpnt, dfixpnt, rational, positional |
| Standard IEEE-754 | quarter/fp8, half/fp16, single/fp32, duble/fp64, quad/fp128, octo/fp256 |
| Configurable Float | cfloat, bfloat16, areal, dfloat, hfloat |
| AI Quantization | microfloat, e8m0, mxfloat, nvblock |
| Unum Family | unum (Type I), unum2 (Type II), posit (Type III), takum |
| Logarithmic | lns, dbns |
| Interval & Uncertainty | interval, sorn, bisection, faithful |
| Extended Precision | dd, qd, dd_cascade, td_cascade, qd_cascade |
| Kulisch Super-Accumulator | quire for half, float, double, cfloat, posit, fixpnt, lns, dbns, integer |
| Category | Types |
|---|---|
| Adaptive Integer | einteger |
| Adaptive Decimal | edecimal |
| Adaptive Rational | erational |
| Adaptive Float | efloat |
| Adaptive Real | ereal – expansion-based, precision set at compile time |
| Lazy Unbounded Real | elreal – refines on demand, no precision ceiling |
Please cite our JOSS paper if you use Universal in your work.