Add big integer implementation
This commit is contained in:
@@ -12,6 +12,7 @@ include(CheckSymbolExists)
|
||||
|
||||
# Project settings
|
||||
option(BH_PLATFORM_THREADS "Enable multithreading support" TRUE)
|
||||
option(BH_BIGINT_LONG "Use bigger internal units for big integer calculations" TRUE)
|
||||
|
||||
# Check for IPO/LTO
|
||||
check_ipo_supported(RESULT supported)
|
||||
@@ -34,6 +35,7 @@ set(BH_SOURCE
|
||||
src/thread.c
|
||||
src/io.c
|
||||
src/deflate.c
|
||||
src/bigint.c
|
||||
)
|
||||
|
||||
set(BH_HEADER
|
||||
@@ -46,6 +48,7 @@ set(BH_HEADER
|
||||
include/bh/thread.h
|
||||
include/bh/io.h
|
||||
include/bh/deflate.h
|
||||
include/bh/bigint.h
|
||||
)
|
||||
|
||||
set(BH_INCLUDE_DIRS
|
||||
|
||||
143
include/bh/bigint.h
Normal file
143
include/bh/bigint.h
Normal file
@@ -0,0 +1,143 @@
|
||||
#ifndef BH_BIGINT_H
|
||||
#define BH_BIGINT_H
|
||||
|
||||
#include "bh.h"
|
||||
|
||||
typedef struct bh_bigint_s bh_bigint_t;
|
||||
|
||||
bh_bigint_t *bh_bigint_new(void);
|
||||
void bh_bigint_free(bh_bigint_t *bigint);
|
||||
|
||||
int bh_bigint_block(void);
|
||||
|
||||
int bh_bigint_clear(bh_bigint_t *bigint);
|
||||
|
||||
int bh_bigint_set(bh_bigint_t *to,
|
||||
bh_bigint_t *from);
|
||||
|
||||
int bh_bigint_set_int(bh_bigint_t *to,
|
||||
int from);
|
||||
|
||||
int bh_bigint_set_uint(bh_bigint_t *to,
|
||||
unsigned int from);
|
||||
|
||||
int bh_bigint_get_int(bh_bigint_t *bigint);
|
||||
|
||||
unsigned int bh_bigint_get_uint(bh_bigint_t *bigint);
|
||||
|
||||
int bh_bigint_set_int8(bh_bigint_t *to,
|
||||
bh_int8_t from);
|
||||
|
||||
int bh_bigint_set_uint8(bh_bigint_t *to,
|
||||
bh_uint8_t from);
|
||||
|
||||
bh_int8_t bh_bigint_get_int8(bh_bigint_t *bigint);
|
||||
|
||||
bh_uint8_t bh_bigint_get_uint8(bh_bigint_t *bigint);
|
||||
|
||||
int bh_bigint_set_int16(bh_bigint_t *to,
|
||||
bh_int16_t from);
|
||||
|
||||
int bh_bigint_set_uint16(bh_bigint_t *to,
|
||||
bh_uint16_t from);
|
||||
|
||||
bh_int16_t bh_bigint_get_int16(bh_bigint_t *bigint);
|
||||
|
||||
bh_uint16_t bh_bigint_get_uint16(bh_bigint_t *bigint);
|
||||
|
||||
int bh_bigint_set_int32(bh_bigint_t *to,
|
||||
bh_int32_t from);
|
||||
|
||||
int bh_bigint_set_uint32(bh_bigint_t *to,
|
||||
bh_uint32_t from);
|
||||
|
||||
bh_int32_t bh_bigint_get_int32(bh_bigint_t *bigint);
|
||||
|
||||
bh_uint32_t bh_bigint_get_uint32(bh_bigint_t *bigint);
|
||||
|
||||
int bh_bigint_set_int64(bh_bigint_t *to,
|
||||
bh_int64_t from);
|
||||
|
||||
int bh_bigint_set_uint64(bh_bigint_t *to,
|
||||
bh_uint64_t from);
|
||||
|
||||
bh_int64_t bh_bigint_get_int64(bh_bigint_t *bigint);
|
||||
|
||||
bh_uint64_t bh_bigint_get_uint64(bh_bigint_t *bigint);
|
||||
|
||||
size_t bh_bigint_capacity(bh_bigint_t *bigint);
|
||||
|
||||
size_t bh_bigint_length(bh_bigint_t *bigint);
|
||||
|
||||
int bh_bigint_reserve(bh_bigint_t *bigint,
|
||||
size_t size);
|
||||
|
||||
int bh_bigint_add(bh_bigint_t *to,
|
||||
bh_bigint_t *left,
|
||||
bh_bigint_t *right);
|
||||
|
||||
int bh_bigint_sub(bh_bigint_t *to,
|
||||
bh_bigint_t *left,
|
||||
bh_bigint_t *right);
|
||||
|
||||
int bh_bigint_mul(bh_bigint_t *to,
|
||||
bh_bigint_t *left,
|
||||
bh_bigint_t *right);
|
||||
|
||||
int bh_bigint_pow(bh_bigint_t *to,
|
||||
bh_bigint_t *from,
|
||||
bh_uint32_t power);
|
||||
|
||||
int bh_bigint_powm(bh_bigint_t *to,
|
||||
bh_bigint_t *left,
|
||||
bh_bigint_t *right,
|
||||
bh_bigint_t *mod);
|
||||
|
||||
int bh_bigint_divmod(bh_bigint_t *quotient,
|
||||
bh_bigint_t *remainder,
|
||||
bh_bigint_t *left,
|
||||
bh_bigint_t *right);
|
||||
|
||||
int bh_bigint_div(bh_bigint_t *to,
|
||||
bh_bigint_t *left,
|
||||
bh_bigint_t *right);
|
||||
|
||||
int bh_bigint_mod(bh_bigint_t *to,
|
||||
bh_bigint_t *left,
|
||||
bh_bigint_t *right);
|
||||
|
||||
int bh_bigint_lsh(bh_bigint_t *to,
|
||||
bh_bigint_t *from,
|
||||
bh_uint32_t shift);
|
||||
|
||||
int bh_bigint_rsh(bh_bigint_t *to,
|
||||
bh_bigint_t *from,
|
||||
bh_uint32_t shift);
|
||||
|
||||
int bh_bigint_or(bh_bigint_t *to,
|
||||
bh_bigint_t *left,
|
||||
bh_bigint_t *right);
|
||||
|
||||
int bh_bigint_and(bh_bigint_t *to,
|
||||
bh_bigint_t *left,
|
||||
bh_bigint_t *right);
|
||||
|
||||
int bh_bigint_xor(bh_bigint_t *to,
|
||||
bh_bigint_t *left,
|
||||
bh_bigint_t *right);
|
||||
|
||||
int bh_bigint_negate(bh_bigint_t *to,
|
||||
bh_bigint_t *from);
|
||||
|
||||
int bh_bigint_equal(bh_bigint_t *left,
|
||||
bh_bigint_t *right);
|
||||
|
||||
int bh_bigint_equal_mod(bh_bigint_t *left,
|
||||
bh_bigint_t *right);
|
||||
|
||||
int bh_bigint_is_negative(bh_bigint_t *bigint);
|
||||
int bh_bigint_is_zero(bh_bigint_t *bigint);
|
||||
int bh_bigint_is_error(bh_bigint_t *bigint);
|
||||
size_t bh_bigint_log2(bh_bigint_t *bigint);
|
||||
|
||||
#endif /* BH_BIGINT_H */
|
||||
31
include/bh/internal/bigint.h
Normal file
31
include/bh/internal/bigint.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef BH_INTERNAL_BIGINT_H
|
||||
#define BH_INTERNAL_BIGINT_H
|
||||
|
||||
#include "bh.h"
|
||||
#include <bh/bigint.h>
|
||||
|
||||
#if defined(BH_BIGINT_LONG)
|
||||
#define BH_BIGINT_BITS 31
|
||||
#define BH_BIGINT_MASK 0x7FFFFFFF
|
||||
#define BH_BIGINT_TYPE bh_uint32_t
|
||||
#define BH_BIGINT_TMP bh_uint64_t
|
||||
#else
|
||||
#define BH_BIGINT_BITS 15
|
||||
#define BH_BIGINT_MASK 0x7FFF
|
||||
#define BH_BIGINT_TYPE bh_uint16_t
|
||||
#define BH_BIGINT_TMP bh_uint32_t
|
||||
#endif
|
||||
|
||||
struct bh_bigint_s
|
||||
{
|
||||
BH_BIGINT_TYPE *data;
|
||||
size_t size;
|
||||
size_t capacity;
|
||||
int type;
|
||||
int error;
|
||||
};
|
||||
|
||||
void bh_bigint_init(bh_bigint_t *bigint);
|
||||
void bh_bigint_destroy(bh_bigint_t *bigint);
|
||||
|
||||
#endif /* BH_INTERNAL_BIGINT_H */
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef BH_INTERNAL_CONFIG_H
|
||||
#define BH_INTERNAL_CONFIG_H
|
||||
|
||||
#cmakedefine BH_BIGINT_LONG
|
||||
#cmakedefine BH_THREADS_WINXP
|
||||
|
||||
#endif /* BH_INTERNAL_CONFIG_H */
|
||||
1558
src/bigint.c
Normal file
1558
src/bigint.c
Normal file
File diff suppressed because it is too large
Load Diff
429
tests/src/bigint.c
Normal file
429
tests/src/bigint.c
Normal file
@@ -0,0 +1,429 @@
|
||||
#include <bh/internal/bigint.h>
|
||||
#include <bh/unit.h>
|
||||
#include <string.h>
|
||||
|
||||
static int round_trip(void)
|
||||
{
|
||||
bh_bigint_t *data[10];
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
data[i] = bh_bigint_new();
|
||||
bh_unit_assert(data[i] != NULL);
|
||||
}
|
||||
|
||||
bh_unit_assert(bh_bigint_set_int(data[0], -12345) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_int(data[0]) == -12345);
|
||||
|
||||
bh_unit_assert(bh_bigint_set_int8(data[1], -120) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_int8(data[1]) == -120);
|
||||
|
||||
bh_unit_assert(bh_bigint_set_int16(data[2], -12345) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_int16(data[2]) == -12345);
|
||||
|
||||
bh_unit_assert(bh_bigint_set_int32(data[3], -12345678l) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_int32(data[3]) == -12345678l);
|
||||
|
||||
bh_unit_assert(bh_bigint_set_int64(data[4], -123456789012345ll) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_int64(data[4]) == -123456789012345ll);
|
||||
|
||||
bh_unit_assert(bh_bigint_set_uint(data[5], 12345) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_uint(data[5]) == 12345);
|
||||
|
||||
bh_unit_assert(bh_bigint_set_uint8(data[6], 230) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_uint8(data[6]) == 230);
|
||||
|
||||
bh_unit_assert(bh_bigint_set_uint16(data[7], 40000) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_uint16(data[7]) == 40000);
|
||||
|
||||
bh_unit_assert(bh_bigint_set_uint32(data[8], 12345678ul) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_uint32(data[8]) == 12345678ul);
|
||||
|
||||
bh_unit_assert(bh_bigint_set_uint64(data[9], 123456789012345ull) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_uint64(data[9]) == 123456789012345ull);
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
bh_bigint_free(data[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int addition(void)
|
||||
{
|
||||
bh_bigint_t *a, *b, *c;
|
||||
bh_uint64_t ta, tb;
|
||||
|
||||
a = bh_bigint_new();
|
||||
b = bh_bigint_new();
|
||||
c = bh_bigint_new();
|
||||
|
||||
bh_unit_assert(a != NULL);
|
||||
bh_unit_assert(b != NULL);
|
||||
bh_unit_assert(c != NULL);
|
||||
|
||||
ta = 0xA3B1DBC158176B96ull;
|
||||
tb = 0x2748D1622F3E90A2ull;
|
||||
|
||||
bh_unit_assert(bh_bigint_set_uint64(a, ta) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_set_uint64(b, tb) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_add(c, a, b) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_uint64(c) == (ta + tb));
|
||||
|
||||
bh_bigint_free(a);
|
||||
bh_bigint_free(b);
|
||||
bh_bigint_free(c);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int subtraction(void)
|
||||
{
|
||||
bh_bigint_t *a, *b, *c;
|
||||
bh_uint64_t ta, tb;
|
||||
|
||||
a = bh_bigint_new();
|
||||
b = bh_bigint_new();
|
||||
c = bh_bigint_new();
|
||||
|
||||
bh_unit_assert(a != NULL);
|
||||
bh_unit_assert(b != NULL);
|
||||
bh_unit_assert(c != NULL);
|
||||
|
||||
ta = 0xA3B1DBC158176B96ull;
|
||||
tb = 0x2748D1622F3E90A2ull;
|
||||
|
||||
bh_unit_assert(bh_bigint_set_uint64(a, ta) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_set_uint64(b, tb) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_sub(c, a, b) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_uint64(c) == (ta - tb));
|
||||
|
||||
bh_bigint_free(a);
|
||||
bh_bigint_free(b);
|
||||
bh_bigint_free(c);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int addition_sign(void)
|
||||
{
|
||||
bh_bigint_t *a, *b, *c;
|
||||
|
||||
a = bh_bigint_new();
|
||||
b = bh_bigint_new();
|
||||
c = bh_bigint_new();
|
||||
|
||||
bh_unit_assert(a != NULL);
|
||||
bh_unit_assert(b != NULL);
|
||||
bh_unit_assert(c != NULL);
|
||||
|
||||
bh_unit_assert(bh_bigint_set_int(a, 5) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_set_int(b, 3) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_add(c, a, b) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_int(c) == 8);
|
||||
bh_unit_assert(bh_bigint_add(c, b, a) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_int(c) == 8);
|
||||
|
||||
bh_unit_assert(bh_bigint_set_int(a, -5) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_set_int(b, 3) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_add(c, a, b) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_int(c) == -2);
|
||||
bh_unit_assert(bh_bigint_add(c, b, a) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_int(c) == -2);
|
||||
|
||||
bh_unit_assert(bh_bigint_set_int(a, 5) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_set_int(b, -3) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_add(c, a, b) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_int(c) == 2);
|
||||
bh_unit_assert(bh_bigint_add(c, b, a) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_int(c) == 2);
|
||||
|
||||
bh_unit_assert(bh_bigint_set_int(a, -5) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_set_int(b, -3) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_add(c, a, b) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_int(c) == -8);
|
||||
bh_unit_assert(bh_bigint_add(c, b, a) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_int(c) == -8);
|
||||
|
||||
bh_bigint_free(a);
|
||||
bh_bigint_free(b);
|
||||
bh_bigint_free(c);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int subtraction_sign(void)
|
||||
{
|
||||
bh_bigint_t *a, *b, *c;
|
||||
|
||||
a = bh_bigint_new();
|
||||
b = bh_bigint_new();
|
||||
c = bh_bigint_new();
|
||||
|
||||
bh_unit_assert(a != NULL);
|
||||
bh_unit_assert(b != NULL);
|
||||
bh_unit_assert(c != NULL);
|
||||
|
||||
bh_unit_assert(bh_bigint_set_int(a, 5) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_set_int(b, 3) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_sub(c, a, b) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_int(c) == 2);
|
||||
bh_unit_assert(bh_bigint_sub(c, b, a) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_int(c) == -2);
|
||||
|
||||
bh_unit_assert(bh_bigint_set_int(a, -5) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_set_int(b, 3) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_sub(c, a, b) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_int(c) == -8);
|
||||
bh_unit_assert(bh_bigint_sub(c, b, a) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_int(c) == 8);
|
||||
|
||||
bh_unit_assert(bh_bigint_set_int(a, 5) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_set_int(b, -3) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_sub(c, a, b) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_int(c) == 8);
|
||||
bh_unit_assert(bh_bigint_sub(c, b, a) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_int(c) == -8);
|
||||
|
||||
bh_unit_assert(bh_bigint_set_int(a, -5) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_set_int(b, -3) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_sub(c, a, b) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_int(c) == -2);
|
||||
bh_unit_assert(bh_bigint_sub(c, b, a) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_int(c) == 2);
|
||||
|
||||
bh_bigint_free(a);
|
||||
bh_bigint_free(b);
|
||||
bh_bigint_free(c);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int multiplication(void)
|
||||
{
|
||||
int i;
|
||||
bh_bigint_t *a, *b, *c, *d;
|
||||
|
||||
a = bh_bigint_new();
|
||||
b = bh_bigint_new();
|
||||
c = bh_bigint_new();
|
||||
d = bh_bigint_new();
|
||||
|
||||
bh_unit_assert(a != NULL);
|
||||
bh_unit_assert(b != NULL);
|
||||
bh_unit_assert(c != NULL);
|
||||
bh_unit_assert(d != NULL);
|
||||
|
||||
bh_unit_assert(bh_bigint_set_int(a, 1234567) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_set_int(b, 1234567) == BH_OK);
|
||||
|
||||
bh_unit_assert(bh_bigint_mul(c, a, b) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_set(d, a) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_reserve(d, d->size + a->size + 1) == BH_OK);
|
||||
|
||||
for (i = 1; i < 1234567; i++)
|
||||
bh_unit_assert(bh_bigint_add(d, d, a) == BH_OK);
|
||||
|
||||
bh_unit_assert(bh_bigint_equal(c, d) == 0);
|
||||
bh_unit_assert(memcmp(c->data, d->data, c->size * sizeof(*c->data)) == 0);
|
||||
|
||||
bh_unit_assert(bh_bigint_set_int(c, 6) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_set_int(b, 2) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_set_int(d, 6) == BH_OK);
|
||||
|
||||
for (i = 0; i < 250; i++)
|
||||
{
|
||||
bh_unit_assert(bh_bigint_mul(c, c, b) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_add(d, d, d) == BH_OK);
|
||||
}
|
||||
|
||||
bh_unit_assert(bh_bigint_equal(c, d) == 0);
|
||||
bh_unit_assert(memcmp(c->data, d->data, c->size * sizeof(*c->data)) == 0);
|
||||
|
||||
bh_bigint_free(a);
|
||||
bh_bigint_free(b);
|
||||
bh_bigint_free(c);
|
||||
bh_bigint_free(d);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int logic(void)
|
||||
{
|
||||
bh_bigint_t *a, *b, *c;
|
||||
bh_uint64_t ta, tb;
|
||||
|
||||
ta = 0xA3B1DBC158176B96ull;
|
||||
tb = 0x2748D1622F3E90A2ull;
|
||||
|
||||
a = bh_bigint_new();
|
||||
b = bh_bigint_new();
|
||||
c = bh_bigint_new();
|
||||
|
||||
bh_unit_assert(a != NULL);
|
||||
bh_unit_assert(b != NULL);
|
||||
bh_unit_assert(c != NULL);
|
||||
|
||||
bh_unit_assert(bh_bigint_set_uint64(a, ta) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_set_uint64(b, tb) == BH_OK);
|
||||
|
||||
bh_unit_assert(bh_bigint_or(c, a, b) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_uint64(c) == (ta | tb));
|
||||
|
||||
bh_unit_assert(bh_bigint_and(c, a, b) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_uint64(c) == (ta & tb));
|
||||
|
||||
bh_unit_assert(bh_bigint_xor(c, a, b) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_uint64(c) == (ta ^ tb));
|
||||
|
||||
bh_bigint_free(a);
|
||||
bh_bigint_free(b);
|
||||
bh_bigint_free(c);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int shifts(void)
|
||||
{
|
||||
bh_bigint_t *a, *b;
|
||||
bh_uint64_t ta, tb;
|
||||
|
||||
ta = 0x73B1DBC158176B96ull;
|
||||
tb = 0x73B1DBC158176B90ull;
|
||||
|
||||
a = bh_bigint_new();
|
||||
b = bh_bigint_new();
|
||||
|
||||
bh_unit_assert(a != NULL);
|
||||
bh_unit_assert(b != NULL);
|
||||
|
||||
bh_unit_assert(bh_bigint_set_uint64(a, 0xFFull) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_lsh(b, a, 4) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_uint64(b) == (0xFFull << 4));
|
||||
|
||||
bh_unit_assert(bh_bigint_set_uint64(a, 0xFFull) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_lsh(b, a, 15) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_uint64(b) == (0xFFull << 15));
|
||||
|
||||
bh_unit_assert(bh_bigint_set_uint64(a, 0xFFull) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_lsh(b, a, 31) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_uint64(b) == (0xFFull << 31));
|
||||
|
||||
bh_unit_assert(bh_bigint_set_uint64(a, 0xFFull) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_lsh(b, a, 35) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_uint64(b) == (0xFFull << 35));
|
||||
|
||||
bh_unit_assert(bh_bigint_set_uint64(a, ta) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_lsh(b, a, 1) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_uint64(b) == (ta << 1));
|
||||
|
||||
bh_unit_assert(bh_bigint_set_uint64(a, ta) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_rsh(b, a, 31) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_uint64(b) == (ta >> 31))
|
||||
|
||||
bh_unit_assert(bh_bigint_set_uint64(a, ta) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_rsh(b, a, 15) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_uint64(b) == (ta >> 15))
|
||||
|
||||
bh_unit_assert(bh_bigint_set_uint64(a, ta) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_rsh(b, a, 4) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_uint64(b) == (ta >> 4));
|
||||
|
||||
bh_unit_assert(bh_bigint_lsh(b, b, 4) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_uint64(b) == tb);
|
||||
|
||||
bh_unit_assert(bh_bigint_rsh(b, a, 60) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_get_uint64(b) == 0x7);
|
||||
|
||||
bh_bigint_free(a);
|
||||
bh_bigint_free(b);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int division(void)
|
||||
{
|
||||
bh_bigint_t *a, *b, *c, *d;
|
||||
|
||||
a = bh_bigint_new();
|
||||
b = bh_bigint_new();
|
||||
c = bh_bigint_new();
|
||||
d = bh_bigint_new();
|
||||
|
||||
bh_unit_assert(a != NULL);
|
||||
bh_unit_assert(b != NULL);
|
||||
bh_unit_assert(c != NULL);
|
||||
bh_unit_assert(d != NULL);
|
||||
|
||||
bh_unit_assert(bh_bigint_set_uint64(a, 0x41F915031348A134ull) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_set_uint64(b, 0x434115F6ull) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_mul(a, a, b) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_set_uint64(b, 0x153F14ABull) == BH_OK);
|
||||
|
||||
bh_unit_assert(bh_bigint_divmod(c, d, a, b) == BH_OK);
|
||||
|
||||
bh_unit_assert(bh_bigint_get_uint64(c) == 0xD0D561E41F7EA081ull);
|
||||
bh_unit_assert(bh_bigint_get_uint64(d) == 0x0459E1CDull);
|
||||
|
||||
bh_bigint_free(a);
|
||||
bh_bigint_free(b);
|
||||
bh_bigint_free(c);
|
||||
bh_bigint_free(d);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int power(void)
|
||||
{
|
||||
bh_bigint_t *a, *b, *c, *d, *e;
|
||||
|
||||
a = bh_bigint_new();
|
||||
b = bh_bigint_new();
|
||||
c = bh_bigint_new();
|
||||
d = bh_bigint_new();
|
||||
e = bh_bigint_new();
|
||||
|
||||
bh_unit_assert(a != NULL);
|
||||
bh_unit_assert(b != NULL);
|
||||
bh_unit_assert(c != NULL);
|
||||
bh_unit_assert(d != NULL);
|
||||
bh_unit_assert(e != NULL);
|
||||
|
||||
bh_unit_assert(bh_bigint_set_int(a, 137) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_set_int(b, 2048) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_set_int(c, 100) == BH_OK);
|
||||
|
||||
bh_unit_assert(bh_bigint_pow(d, a, 2048) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_mod(d, d, c) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_powm(e, a, b, c) == BH_OK);
|
||||
bh_unit_assert(bh_bigint_equal(d, e) == 0);
|
||||
bh_unit_assert(bh_bigint_get_int(d) == 21);
|
||||
|
||||
bh_bigint_free(a);
|
||||
bh_bigint_free(b);
|
||||
bh_bigint_free(c);
|
||||
bh_bigint_free(d);
|
||||
bh_bigint_free(e);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
/* Add unit tests */
|
||||
bh_unit_add("round_trip", round_trip);
|
||||
bh_unit_add("addition", addition);
|
||||
bh_unit_add("subtraction", subtraction);
|
||||
bh_unit_add("addition_sign", addition_sign);
|
||||
bh_unit_add("subtraction_sign", subtraction_sign);
|
||||
bh_unit_add("multiplication", multiplication);
|
||||
bh_unit_add("logic", logic);
|
||||
bh_unit_add("shifts", shifts);
|
||||
bh_unit_add("division", division);
|
||||
bh_unit_add("power", power);
|
||||
|
||||
return bh_unit_run();
|
||||
}
|
||||
Reference in New Issue
Block a user