Big number library written in C++17
-
+, -, *, /, mod, &, |, ~, ==, >=, >, ... (more operations)
-
eval("<a valid infix expression>") (support calling builtin functions & ref builtin constants)
git clone https://github.com/PGZXB/PGBigNumber.git PGBigNumber
cd PGBigNumber
mkdir build
cd build
PGBN_BUILD_TESTS=1 cmake ..
make
./tests/test_for_calcu # Optional, to verify correctness
cd ..
cd ..
- Clone the repo
- Run cmake (generate VS project)
- Open project & Build
ALL_BUILD
Set PGBigNumber/include as include dir.
Link static lib PGBigNumber
(and PGBigNumberBindingC
for C).
- Using in C++. simple.cpp:
#include <cassert>
#include <iostream>
#include "PGBigNumber/BigInteger.h"
#include "PGBigNumber/expr.h"
using namespace pgbn;
using namespace pgbn::expr;
int main() {
BigInteger a("1000000000000000000000000000000000000");
BigInteger b("2");
BigInteger c("-1000000000000000000000000000000000000");
auto d = a * b;
assert(d.toString() == "2000000000000000000000000000000000000");
d /= c;
assert(d.toString() == "-2");
auto expr = pgfmt::format("{0} * {1} / {2} == {3}",
a.toString(), b.toString(), c.toString(), d.toString());
std::cout << expr << '\n';
auto eval_expr = eval(expr);
assert(eval_expr.isOne() && eval_expr.toString() == "1");
std::cout << pgfmt::format("{0}: {1}", expr, eval_expr.as<bool>()) << '\n';
return 0;
}
- Using eval & peval. test_for_eval.cpp
peval <=> parallel-eval
#include "expr.h"
#include <chrono>
using namespace pgbn;
using namespace pgbn::expr;
struct ScopedTimeCounter {
std::size_t nanosec{0};
const std::string name{nullptr};
ScopedTimeCounter(const std::string & name) : name(name) {
using std::chrono::system_clock;
nanosec = system_clock::now().time_since_epoch().count();
}
~ScopedTimeCounter() {
using std::chrono::system_clock;
nanosec = system_clock::now().time_since_epoch().count() - nanosec;
std::cerr << pgfmt::format("{0} : {1}ns\n", name, nanosec);
}
};
int main() {
auto simpleExpr = "(30000! + 30000! + 30000! + 30000! + 30000! + 30000! + 30000! + 30000!) + (30000! + 30000! + 30000! + 30000! + 30000! + 30000! + 30000! + 30000!)";
{
ScopedTimeCounter _(pgfmt::format("peval {0}", simpleExpr));
peval(simpleExpr);
}
{
ScopedTimeCounter _(pgfmt::format(" eval {0}", simpleExpr));
eval(simpleExpr);
}
return 0;
}
./tests/test_for_eval
Output:
# In My VM
peval (30000! + 30000! + 30000! + 30000! + 30000! + 30000! + 30000! + 30000!) + (30000! + 30000! + 30000! + 30000! + 30000! + 30000! + 30000! + 30000!) : 23513704467ns
eval (30000! + 30000! + 30000! + 30000! + 30000! + 30000! + 30000! + 30000!) + (30000! + 30000! + 30000! + 30000! + 30000! + 30000! + 30000! + 30000!) : 61925004957ns
- Using in C. simple.c
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "PGBigNumber/pgbn.h"
int main() {
pgbn_BigInteger_t *a = pgbn_BigInteger_CreateWithStr("1000000000000000000000000000000000000", 10);
pgbn_BigInteger_t *b = pgbn_BigInteger_CreateWithStr("2", 10);
pgbn_BigInteger_t *c = pgbn_BigInteger_CreateWithStr("-1000000000000000000000000000000000000", 10);
pgbn_String_t *a_str = pgbn_BigInteger_ToString(a, 10);
pgbn_String_t *b_str = pgbn_BigInteger_ToString(b, 10);
pgbn_String_t *c_str = pgbn_BigInteger_ToString(c, 10);
// d = a * b
pgbn_BigInteger_t *d = pgbn_BigInteger_CreateWithCopying(a);
pgbn_BigInteger_MulAssign(d, b);
pgbn_String_t *d_str = pgbn_BigInteger_ToString(d, 10);
assert(strcmp((pgbn_String_CStr(d_str)), "2000000000000000000000000000000000000") == 0);
pgbn_String_Destroy(d_str);
// d /= c
pgbn_BigInteger_DivAssign(d, c);
d_str = pgbn_BigInteger_ToString(d, 10);
assert(strcmp((pgbn_String_CStr(d_str)), "-2") == 0);
printf("%s * %s / %s == %s",
pgbn_String_CStr(a_str),
pgbn_String_CStr(b_str),
pgbn_String_CStr(c_str),
pgbn_String_CStr(d_str)
);
// Destroy
pgbn_BigInteger_Destroy(a);
pgbn_BigInteger_Destroy(b);
pgbn_BigInteger_Destroy(c);
pgbn_BigInteger_Destroy(d);
pgbn_String_Destroy(a_str);
pgbn_String_Destroy(b_str);
pgbn_String_Destroy(c_str);
pgbn_String_Destroy(d_str);
return 0;
}