Arbitrary precision arithmetic in C++, even at compile time
arby is a C++ library that provides arbitrary-precision arithmetic integer types.
It is cross-platform, unit-tested and requires some C++20 support for use.
It's also licensed under a weak copyleft license, the Mozilla Public License v2.0.
This allows arby to be used freely in open-source and closed-source projects, with no restrictions. The only main condition related to use is that if you modify arby itself (i.e. any of the files in this repository), you are required to make your modified versions of these files publicly available, so that the community benefits from any potential improvements you make.
arby is not intended at this time to be a serious competitor to other well-established bignum libraries for C/C++ such as GNU's GMP/MPFR, certainly not in terms of portability or performance.
arby is designed with the following goals in mind:
Nat
divmod()
)pow()
)uintmax_t
and long double
Int
Nat
with the exception of bitwise ones (but including bit-shifting)Rat
Int
arby hasn't been benchmarked yet, but it is not expected to perform as well as other long-established bignum libraries for C/C++.
Much of the code is not expected to perform terribly, however it must be noted that converting Nat
to strings is particularly slow for very large numbers. This is an area for potential future optimisation efforts.
arby is alpha-quality software. Although fairly thoroughly unit-tested, more work can be done to make it robust.
In particular, arby currently stores number digits in a custom-made doubly linked list type, due to lack of cross-platform stdlib support for constexpr std::vector
. Nonetheless, this type doesn't work fully in constexpr
contexts on all platforms.
Even with good-quality constexpr
support, language limitations mean one can't store any of arby's types as compile-time constants, however it is possible to store values of other types calculated from arby's types at compile-time, by casting to one of those types and returning such value from a constexpr
or consteval
function. This could be useful if calculation of a value that will fit in a fixed-size variable requires intermediate calculations of arbitrary size. Again, support for this requires good constexpr
support on the platform to work.
Although mostly a header-only library, there are a few routines that are compiled into binary; it's recommended to use CMake for building and installing arby, and further recommended to use CPM to simplify package-management:
CPMFindPackage(
NAME Arby
GIT_REPOSITORY git@github.com:saxbophone/arby.git
GIT_TAG v0.3.0
)
# link your targets against Arby::arby
Short demo program:
#include <iostream>
#include <arby/Nat.hpp>
using namespace com::saxbophone;
int main() {
// powers of 11
for (unsigned int power = 0; power < 20; power++) {
std::cout << arby::pow(11, power) << std::endl;
}
std::cout << arby::pow(2, 64) << std::endl;
// demo of custom literals
using namespace com::saxbophone::arby::literals;
arby::Nat foo = 1234567891011121314151617181920_nat * 77378921_nat;
std::cout << foo << std::endl;
}
Sample output:
1
11
121
1331
14641
161051
1771561
19487171
214358881
2357947691
25937424601
285311670611
3138428376721
34522712143931
379749833583241
4177248169415651
45949729863572161
505447028499293771
5559917313492231481
61159090448414546291
18446744073709551616
95529531307686166289154167942030308320
Full API Docs available at: saxbophone.com/arby/