diff --git a/Makefile b/Makefile index b2dea67..9107c9e 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ all: utest-byte utest-short utest-word utest-quad \ utest-byte-single utest-short-single utest-word-single utest-quad-single \ utest-coverage bigint.o -test: utest-byte utest-short utest-word utest-quad utest-byte-single utest-short-single utest-word-single utest-quad-single utest-coverage +test: utest-byte utest-short utest-word utest-quad utest-byte-single utest-short-single utest-word-single utest-quad-single utest-byte-static utest-short-static utest-word-static utest-quad-static utest-coverage ./utest-byte >/dev/null 2>&1 || ./utest-byte ./utest-short >/dev/null 2>&1 || ./utest-short ./utest-word >/dev/null 2>&1 || ./utest-word diff --git a/bigint.h b/bigint.h index f6af5ed..cc74b78 100644 --- a/bigint.h +++ b/bigint.h @@ -146,6 +146,9 @@ int bigint_from_cstring(bigint* b, const char* str, unsigned int base); BIGINT_API size_t bigint_to_string(char* str, size_t len, const bigint* b, unsigned int base); +BIGINT_API +int bigint_cmp(const bigint *a, const bigint *b); + BIGINT_API int bigint_inc(bigint* c, const bigint *a); @@ -164,13 +167,6 @@ int bigint_mul(bigint* c, const bigint* a, const bigint* b); BIGINT_API int bigint_div_mod(bigint* quotient, bigint* remainder, const bigint* numerator, const bigint* denominator); -/* faster div_mod for when you're dividing by a regular, positive word type - note that this - * overwrites numerator! roughly equivalent to: - * remainder = numerator % denominator - * numerator /= denominator */ -BIGINT_API -void bigint_div_mod_word(bigint* numerator, bigint_word* remainder, bigint_word denominator); - BIGINT_API int bigint_lshift(bigint* c, const bigint* a, size_t bits); @@ -183,6 +179,13 @@ int bigint_lshift_overwrite(bigint* a, size_t bits); BIGINT_API int bigint_rshift_overwrite(bigint* a, size_t bits); +/* faster div_mod for when you're dividing by a regular, positive word type - note that this + * overwrites numerator! roughly equivalent to: + * remainder = numerator % denominator + * numerator /= denominator */ +BIGINT_API +void bigint_div_mod_word(bigint* numerator, bigint_word* remainder, bigint_word denominator); + #ifdef __cplusplus } #endif @@ -1623,4 +1626,12 @@ size_t bigint_to_string(char* str, size_t len, const bigint* b, unsigned int bas return res; } +BIGINT_API +int bigint_cmp(const bigint *a, const bigint *b) { + if(!a->size && !b->size) return 0; + if(a->sign && b->sign) return bigint_cmp_abs(b,a); + if(a->sign == b->sign) return bigint_cmp_abs(a,b); + return a->sign && !b->sign ? -1 : 1; +} + #endif diff --git a/utest.c b/utest.c index a8d7d07..942c1f9 100644 --- a/utest.c +++ b/utest.c @@ -2607,4 +2607,40 @@ UTEST(bigint,from_int64) { bigint_free(&a); } + +UTEST(bigint,cmp) { + PREAMBLE + + ASSERT_EQ(bigint_cmp(&a,&b),0); + ASSERT_EQ(bigint_cmp(&b,&a),0); + + ASSERT_EQ(bigint_from_u8(&a,1),0); + ASSERT_EQ(bigint_cmp(&a,&b),1); + ASSERT_EQ(bigint_cmp(&b,&a),-1); + + ASSERT_EQ(bigint_from_u8(&b,1),0); + + ASSERT_EQ(bigint_cmp(&a,&b),0); + ASSERT_EQ(bigint_cmp(&b,&a),0); + + ASSERT_EQ(bigint_from_u8(&a,0),0); + ASSERT_EQ(bigint_cmp(&a,&b),-1); + ASSERT_EQ(bigint_cmp(&b,&a),1); + + ASSERT_EQ(bigint_from_u8(&a,1),0); + a.sign = 1; + ASSERT_EQ(bigint_cmp(&a,&b),-1); + ASSERT_EQ(bigint_cmp(&b,&a),1); + + b.sign = 1; + ASSERT_EQ(bigint_cmp(&a,&b),0); + ASSERT_EQ(bigint_cmp(&b,&a),0); + + a.sign = 0; + ASSERT_EQ(bigint_cmp(&a,&b),1); + ASSERT_EQ(bigint_cmp(&b,&a),-1); + + CLEANUP +} + UTEST_MAIN();