But also Big Signed Integers and Big Decimal numbers.
C library providing fixed length integer types longer than 32/64 bits. The key design concepts of libbiguint are:
- Fast operations.
- Versatile function set.
- Supporting different hardware platforms.
- No dynamic memory handling.
- Only essential dependencies.
- Configurability and modularity.
All these make libbiguint suitable for embedded systems.
libbiguint provides the following unsigned integer types:
BigUInt128
(128 bits)BigUInt256
(256 bits)BigUInt384
(384 bits)BigUInt512
(512 bits)BigUInt<number>
(1024 or even more bits)
All the provided types are accompanied by the following functions:
- addition and subtraction (add, sub, inc, dec, adc, sbc);
- multiplication and division (mul, dmul, div/mod);
- bit shift operations (shl, shr, rol, ror);
- bitwise operations (and, or, xor, not);
- bitwise manipulation (get, set, clr, overwrite);
- comparison (lt, eq, eqz);
- parsing and printing (from/to hex and dec strings);
- default and standard constructors (initializer functions).
The source code of type BigUInt128
is written in general manner.
The source of all other biguint types are generated codes derived from BigUInt128
.
Types BigUInt256
, BigUInt384
, BigUInt512
and BigUInt<N>
and
adherent functions are optionally generated:
the 256, 384 and 512 bit wide types are enabled by default, the N bit wide type is disabled.
See configure --help
for details.
There are no explicit BigInt<number>
types.
We can store the signed big integers in BigUInt types.
And most of the BigUInt functions work perfectly with BigInts.
However, there are some functions which work differently for signed and unsigned integers,
therefore they have their BigInt variants:
- parsing and printing (only dec strings);
- comparison (lt, ltz);
- division (div) and inversion (negate).
Based on the corresponding BigUInt type, the following BigDecimal types are available:
BigDecimal128
BigDecimal256
BigDecimal384
BigDecimal512
BigDecimal<number>
The functions accompanying these types are:
- addition and subtraction (add, sub);
- multiplication and division (mul, div, div_fast);
- precision adjustment;
- comparison (lt, eq);
- parsing and printing (only decimal format is supported).
All BigDecimal numbers are treated as signed values.
Either clone the git source or download and extract the zip. Cloning git source is preferred. It is easier to update.
First, you need to run aclocal
.
Next, run autoconf
.
Finally, run automake --add-missing
.
aclocal
autoconf
automake --add-missing
The INSTALL file already describes how to run the configure
script.
Installation prefix, compiler, target platform, etc. can be overridden at this step.
./configure
make
make install
The configure
script supports handling different build profiles simultaneously
(see VPATH Builds).
It generates the outputs (Makefiles) in the current working directory, whereever the configure
script has been called.
Executing make
with these generated Makefiles
will put the build output in the directory, where the Makefiles reside.
Well, except for make install
, of course.
You can create and manage multiple profiles, e.g., a Debug and a Release profile, within the base directory of the project:
mkdir -p dist/Debug
cd dist/Debug
../../configure CFLAGS="-O0 -g -W -Wall"
make
cd ../..
and
mkdir -p dist/Release
cd dist/Release
../../configure CFLAGS="-O2"
make
make install
cd ../..
Cross compilation is also supported.
All you have to do is to create a profile for the desired target.
Note, you have to give options --host
and --build
to configure
, see the
online manual.
Read some words about the naming conventions of functions here.
And getting the sum in C string (i.e., 0-terminated char array) as well.
#include <string.h>
#include "biguint128.h"
#define BUFLEN 42
int main() {
const char a_str[]="123456789012345678901234567890";
const char b_str[]="111111111111111111111111111111";
char res_str[BUFLEN];
BigUInt128 a = biguint128_ctor_deccstream(a_str, strlen(a_str));
BigUInt128 b = biguint128_ctor_deccstream(b_str, strlen(b_str));
BigUInt128 res = biguint128_add(&a, &b);
res_str[biguint128_print_dec(&res, res_str, BUFLEN)]=0;
// now res_str contains the sum of a and b in decimal format.
}
10^21 is greater than 2^64.
#include <stdio.h>
#include "biguint128.h"
int main() {
BigUInt128 a = biguint128_value_of_uint(10000000);
BigUInt128 asquare = biguint128_mul(&a,&a);
BigUInt128 acube = biguint128_mul(&a,&asquare);
printf("Highest bit set in a: %d\n", (int)biguint128_msb(&a));
printf("Highest bit set in a^2: %d\n", (int)biguint128_msb(&asquare));
printf("Highest bit set in a^3: %d\n", (int)biguint128_msb(&acube));
return 0;
}