diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | mini-gmp/mini-gmp.c | 48 | ||||
-rw-r--r-- | mini-gmp/mini-gmp.h | 1 |
3 files changed, 54 insertions, 0 deletions
@@ -1,3 +1,8 @@ +2013-01-22 Niels Möller <nisse@lysator.liu.se> + + * mini-gmp/mini-gmp.c (mpz_cmpabs_d): New function. + * mini-gmp/mini-gmp.h: Declare it. + 2013-01-21 Niels Möller <nisse@lysator.liu.se> * mini-gmp/tests/t-str.c (testmain): Test mpz_out_str, using diff --git a/mini-gmp/mini-gmp.c b/mini-gmp/mini-gmp.c index 5d16d76f1..bf1b2dc2f 100644 --- a/mini-gmp/mini-gmp.c +++ b/mini-gmp/mini-gmp.c @@ -1545,6 +1545,54 @@ mpz_get_d (const mpz_t u) } int +mpz_cmpabs_d (const mpz_t x, double d) +{ + mp_size_t xn; + double B, Bi; + mp_size_t i; + + xn = GMP_ABS (x->_mp_size); + d = GMP_ABS (d); + + if (xn == 0) + return - (d > 0.0); + if (d < 1.0) + return 1; + + B = 2.0 * (double) GMP_LIMB_HIGHBIT; + Bi = 1.0 / B; + + /* Scale d so it can be compared with the top limb. */ + for (i = 1; i < xn; i++) + { + d *= Bi; + if (d < 1.0) + return 1; + } + if (d >= B) + return -1; + + /* Subtract x from d, one limb at a time. */ + for (i = xn; i-- > 0;) + { + mp_limb_t f, xl; + + f = (mp_limb_t) d; + xl = x->_mp_d[i]; + if (xl > f) + return 1; + else if (xl < f) + return -1; + d = B * (d - f); + } + + if (d > 0) + return -1; + else + return 0; +} + +int mpz_cmp_d (const mpz_t x, double d) { mp_size_t xn = x->_mp_size; diff --git a/mini-gmp/mini-gmp.h b/mini-gmp/mini-gmp.h index edcaa7555..8c94ca2ed 100644 --- a/mini-gmp/mini-gmp.h +++ b/mini-gmp/mini-gmp.h @@ -108,6 +108,7 @@ int mpz_cmp (const mpz_t, const mpz_t); int mpz_cmpabs_ui (const mpz_t, unsigned long); int mpz_cmpabs (const mpz_t, const mpz_t); int mpz_cmp_d (const mpz_t, double); +int mpz_cmpabs_d (const mpz_t, double); void mpz_abs (mpz_t, const mpz_t); void mpz_neg (mpz_t, const mpz_t); |