einteger: Adaptive-Precision Integer
integer<N> fixes its width at compile time, which is what you want when the number has
to fit a register or an interchange format. When it does not – factorials, combinatorics,
exact rational arithmetic, cryptographic sizes, or the exact oracles this library scores
its own floating-point types against – you want an integer that simply grows.
einteger allocates limbs as the value needs them. There is no overflow, only memory.
#include <universal/number/einteger/einteger.hpp>using namespace sw::universal;
einteger<std::uint32_t> two(2), p(1);for (int i = 0; i < 200; ++i) p = p * two;std::cout << p << '\n';// 1606938044258990275541962092341162602522202993782792835301376template<typename BlockType = std::uint32_t>class einteger;BlockType is the limb type the magnitude is stored in. The value is sign-magnitude, so
the limb array holds the magnitude and the sign rides alongside – there is no two’s
complement wrap, and no most-negative-value asymmetry.
| Property | Value |
|---|---|
| Width | grows with the value |
| Overflow | none |
| Representation | sign + magnitude limb array |
| Default limb | std::uint32_t |
Full arithmetic, comparison, and decimal/hex parsing and printing are provided.
showLimbs() prints the limb encoding when you need to see the representation.
Where it is used
Section titled “Where it is used”einteger backs the exact-arithmetic oracles used to validate the floating-point types.
When a test needs to decide whether a qd or ereal result is correct, it computes the
same quantity as an exact dyadic rational over einteger and compares – so no
floating-point sits between an implementation and its own score.