add comparison function

This commit is contained in:
John Regan
2023-03-20 14:05:46 -04:00
parent 90916aacd6
commit 10c6ae2dd7
3 changed files with 55 additions and 8 deletions

View File

@@ -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-byte-single utest-short-single utest-word-single utest-quad-single \
utest-coverage bigint.o 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-byte >/dev/null 2>&1 || ./utest-byte
./utest-short >/dev/null 2>&1 || ./utest-short ./utest-short >/dev/null 2>&1 || ./utest-short
./utest-word >/dev/null 2>&1 || ./utest-word ./utest-word >/dev/null 2>&1 || ./utest-word

View File

@@ -146,6 +146,9 @@ int bigint_from_cstring(bigint* b, const char* str, unsigned int base);
BIGINT_API BIGINT_API
size_t bigint_to_string(char* str, size_t len, const bigint* b, unsigned int base); 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 BIGINT_API
int bigint_inc(bigint* c, const bigint *a); 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 BIGINT_API
int bigint_div_mod(bigint* quotient, bigint* remainder, const bigint* numerator, const bigint* denominator); 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 BIGINT_API
int bigint_lshift(bigint* c, const bigint* a, size_t bits); 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 BIGINT_API
int bigint_rshift_overwrite(bigint* a, size_t bits); 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 #ifdef __cplusplus
} }
#endif #endif
@@ -1623,4 +1626,12 @@ size_t bigint_to_string(char* str, size_t len, const bigint* b, unsigned int bas
return res; 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 #endif

36
utest.c
View File

@@ -2607,4 +2607,40 @@ UTEST(bigint,from_int64) {
bigint_free(&a); 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(); UTEST_MAIN();