From a11c52e896dad5c8123b3246648fc669a9f8a205 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Wed, 29 Mar 2017 19:56:53 +0200 Subject: [PATCH] Refactor the comparison predicates, check for identity first. --- lib/mpi/cryb_mpi_cmp.c | 17 ++++++----------- lib/mpi/cryb_mpi_cmp_abs.c | 4 +++- lib/mpi/cryb_mpi_eq.c | 7 +++++-- lib/mpi/cryb_mpi_eq_abs.c | 7 +++++-- t/t_mpi_compar.c | 29 +++++++++++++++++++++++++++++ 5 files changed, 48 insertions(+), 16 deletions(-) diff --git a/lib/mpi/cryb_mpi_cmp.c b/lib/mpi/cryb_mpi_cmp.c index 9fef809..690e546 100644 --- a/lib/mpi/cryb_mpi_cmp.c +++ b/lib/mpi/cryb_mpi_cmp.c @@ -43,15 +43,10 @@ int mpi_cmp(const cryb_mpi *X, const cryb_mpi *Y) { - if (X->neg) { - if (Y->neg) - return (-mpi_cmp_abs(X, Y)); - else - return (-1); - } else { - if (Y->neg) - return (1); - else - return (mpi_cmp_abs(X, Y)); - } + if (X == Y) + return (0); + else if (X->neg) + return (Y->neg ? -mpi_cmp_abs(X, Y) : -1); + else + return (Y->neg ? 1 : mpi_cmp_abs(X, Y)); } diff --git a/lib/mpi/cryb_mpi_cmp_abs.c b/lib/mpi/cryb_mpi_cmp_abs.c index bbe8a30..4484534 100644 --- a/lib/mpi/cryb_mpi_cmp_abs.c +++ b/lib/mpi/cryb_mpi_cmp_abs.c @@ -44,7 +44,9 @@ mpi_cmp_abs(const cryb_mpi *X, const cryb_mpi *Y) { int i; - /* check width first */ + /* check trivial cases first */ + if (X == Y) + return (0); if (X->msb > Y->msb) return (1); if (X->msb < Y->msb) diff --git a/lib/mpi/cryb_mpi_eq.c b/lib/mpi/cryb_mpi_eq.c index 90410d3..2ea3a54 100644 --- a/lib/mpi/cryb_mpi_eq.c +++ b/lib/mpi/cryb_mpi_eq.c @@ -43,6 +43,9 @@ int mpi_eq(const cryb_mpi *A, const cryb_mpi *B) { - return (A->neg == B->neg && A->msb == B->msb && - memcmp(A->words, B->words, (A->msb + 31) / 32) == 0); + if (A == B) + return (1); + if (A->neg != B->neg || A->msb != B->msb) + return (0); + return (memcmp(A->words, B->words, (A->msb + 31) / 32) == 0); } diff --git a/lib/mpi/cryb_mpi_eq_abs.c b/lib/mpi/cryb_mpi_eq_abs.c index 5e65715..7e0e21d 100644 --- a/lib/mpi/cryb_mpi_eq_abs.c +++ b/lib/mpi/cryb_mpi_eq_abs.c @@ -43,6 +43,9 @@ int mpi_eq_abs(const cryb_mpi *A, const cryb_mpi *B) { - return (A->msb == B->msb && - memcmp(A->words, B->words, (A->msb + 31) / 32) == 0); + if (A == B) + return (1); + if (A->msb != B->msb) + return (0); + return (memcmp(A->words, B->words, (A->msb + 31) / 32) == 0); } diff --git a/t/t_mpi_compar.c b/t/t_mpi_compar.c index 5e43363..03f30c2 100644 --- a/t/t_mpi_compar.c +++ b/t/t_mpi_compar.c @@ -142,6 +142,33 @@ t_mpi_eq(char **desc CRYB_UNUSED, void *arg) return (ret); } +/* + * Compare an MPI with itself + */ +static int +t_mpi_cmp_ident(char **desc CRYB_UNUSED, void *arg CRYB_UNUSED) +{ + cryb_mpi a = CRYB_MPI_ZERO; + int ret = 1; + + mpi_set(&a, CRYB_TO); + ret &= t_compare_i(0, mpi_cmp(&a, &a)); + mpi_destroy(&a); + return (ret); +} + +static int +t_mpi_eq_ident(char **desc CRYB_UNUSED, void *arg CRYB_UNUSED) +{ + cryb_mpi a = CRYB_MPI_ZERO; + int ret = 1; + + mpi_set(&a, CRYB_TO); + ret &= t_compare_i(1, mpi_eq(&a, &a)); + mpi_destroy(&a); + return (ret); +} + /* * Compare an MPI with an integer */ @@ -187,9 +214,11 @@ t_prepare(int argc, char *argv[]) t_mpi_prepare(); /* comparison */ + t_add_test(t_mpi_cmp_ident, NULL, "mpi cmp mpi (identity)"); for (i = 0; i < sizeof t_cmp_cases / sizeof t_cmp_cases[0]; ++i) t_add_test(t_mpi_cmp, &t_cmp_cases[i], "mpi cmp mpi (%s)", t_cmp_cases[i].desc); + t_add_test(t_mpi_eq_ident, NULL, "mpi eq mpi (identity)"); for (i = 0; i < sizeof t_cmp_cases / sizeof t_cmp_cases[0]; ++i) t_add_test(t_mpi_eq, &t_cmp_cases[i], "mpi eq mpi (%s)", t_cmp_cases[i].desc);