I just started development on a new bignum library that can operate on numbers of any arbitrary base (up to 232). I want to get a good idea of where I can improve before taking things any further. Right now, the library supports basic addition and subtraction, comparisons, and absolute values. I will be adding division, multiplication, modulus, and bit operations soon but now seems as good a time as any to get some feedback.
The library has some typedefs for base 2, 8, 10, 16, and 32 right now, so I'll just give an example using base-10.
#include <iostream>
#include "bignum.h"
/*
* Use with an std::ostream
*/
#define LOG_DEBUG_COMP(x, cmp, y)\
x << BN_STRINGIFY(cmp) << y << ":\t" << (x cmp y)
#define CREATE_BN_TEST(bnType) \
void test_##bnType() { \
std::cout \
<< "------------------------------------------------------------------\n" \
<< "\t\t\t" << BN_STRINGIFY(bnType) << '\n' \
<< "------------------------------------------------------------------\n" \
<< std::endl; \
bnType testNum1 = {bn_desc_t::BN_NEG, {1, bnType::SINGLE_BASE_MAX, bnType::SINGLE_BASE_MAX}}; \
bnType testNum2 = {bn_desc_t::BN_POS, {bnType::SINGLE_BASE_MIN, 1}}; \
\
std::cout << LOG_DEBUG_COMP(testNum1, >, testNum2) << std::endl; \
std::cout << LOG_DEBUG_COMP(testNum1, >=, testNum2) << std::endl; \
std::cout << LOG_DEBUG_COMP(testNum1, <, testNum2) << std::endl; \
std::cout << LOG_DEBUG_COMP(testNum1, <=, testNum2) << std::endl; \
std::cout << std::endl; \
\
std::cout << LOG_DEBUG_COMP(testNum1, +, testNum2) << std::endl; \
std::cout << LOG_DEBUG_COMP(testNum1, -, testNum2) << std::endl; \
std::cout << LOG_DEBUG_COMP(testNum2, +, testNum1) << std::endl; \
std::cout << LOG_DEBUG_COMP(testNum2, -, testNum1) << std::endl; \
std::cout << std::endl; \
\
testNum1.setDescriptor(BN_POS); \
testNum2.setDescriptor(BN_NEG); \
\
std::cout << LOG_DEBUG_COMP(testNum1, >, testNum2) << std::endl; \
std::cout << LOG_DEBUG_COMP(testNum1, >=, testNum2) << std::endl; \
std::cout << LOG_DEBUG_COMP(testNum1, <, testNum2) << std::endl; \
std::cout << LOG_DEBUG_COMP(testNum1, <=, testNum2) << std::endl; \
std::cout << std::endl; \
\
std::cout << LOG_DEBUG_COMP(testNum1, +, testNum2) << std::endl; \
std::cout << LOG_DEBUG_COMP(testNum1, -, testNum2) << std::endl; \
std::cout << LOG_DEBUG_COMP(testNum2, +, testNum1) << std::endl; \
std::cout << LOG_DEBUG_COMP(testNum2, -, testNum1) << std::endl; \
std::cout << "\n\n" << std::endl; \
}
CREATE_BN_TEST(bignum_base8)
CREATE_BN_TEST(bignum_base10)
CREATE_BN_TEST(bignum_base16)
int main() {
try {
test_bignum_base8();
test_bignum_base10();
test_bignum_base16();
}
catch(const std::exception& e) {
std::cerr << "Exception caught: " << e.what() << std::endl;
}
return 0;
}
Here's the output:
------------------------------------------------------------------ bignum_base8 ------------------------------------------------------------------ -177>01: 0 -177>=01: 0 -177<01: 1 -177<=01: 1 -177+01: -176 -177-01: -200 01+-177: -176 01--177: 200 177>-01: 1 177>=-01: 1 177<-01: 0 177<=-01: 0 177+-01: 176 177--01: 200 -01+177: 176 -01-177: -200 ------------------------------------------------------------------ bignum_base10 ------------------------------------------------------------------ -199>01: 0 -199>=01: 0 -199<01: 1 -199<=01: 1 -199+01: -198 -199-01: -200 01+-199: -198 01--199: 200 199>-01: 1 199>=-01: 1 199<-01: 0 199<=-01: 0 199+-01: 198 199--01: 200 -01+199: 198 -01-199: -200 ------------------------------------------------------------------ bignum_base16 ------------------------------------------------------------------ -11515>01: 0 -11515>=01: 0 -11515<01: 1 -11515<=01: 1 -11515+01: -11514 -11515-01: -200 01+-11515: -11514 01--11515: 200 11515>-01: 1 11515>=-01: 1 11515<-01: 0 11515<=-01: 0 11515+-01: 11514 11515--01: 200 -01+11515: 11514 -01-11515: -200
Is there anything that I should improve upon regarding the API or its internals? It makes pretty heavy use of templates (which may harm readability) but I tried making the code as clean as possible, while also using external templates to reduce build times. I'd like to use this in production code but I also want it to be used publicly as well.