static void test_cmp_q (mpfr_prec_t pmin, mpfr_prec_t pmax, int nmax) { mpfr_t x, z; mpq_t y; mpfr_prec_t p; int res1, res2; int n; mpfr_init (x); mpfr_init2 (z, MPFR_PREC_MIN); mpq_init (y); /* check the erange flag when x is NaN */ mpfr_set_nan (x); mpq_set_ui (y, 17, 1); mpfr_clear_erangeflag (); res1 = mpfr_cmp_q (x, y); if (res1 != 0 || mpfr_erangeflag_p () == 0) { printf ("Error for mpfr_cmp_q (NaN, 17)\n"); printf ("Return value: expected 0, got %d\n", res1); printf ("Erange flag: expected set, got %d\n", mpfr_erangeflag_p ()); exit (1); } for(p=pmin ; p < pmax ; p++) { mpfr_set_prec (x, p); for (n = 0 ; n < nmax ; n++) { mpfr_urandomb (x, RANDS); mpq_set_ui (y, randlimb (), randlimb() ); if (!MPFR_IS_SINGULAR (x)) { mpfr_sub_q (z, x, y, MPFR_RNDN); res1 = mpfr_sgn (z); res2 = mpfr_cmp_q (x, y); if (res1 != res2) { printf("Error for mpfr_cmp_q: res=%d sub_z gives %d\n", res2, res1); exit (1); } } } } mpq_clear (y); mpfr_clear (x); mpfr_clear (z); }
static void test_cmp_q (mpfr_prec_t pmin, mpfr_prec_t pmax, int nmax) { mpfr_t x, z; mpq_t y; mpfr_prec_t p; int res1, res2; int n; mpfr_init (x); mpfr_init2 (z, MPFR_PREC_MIN); mpq_init (y); for(p=pmin ; p < pmax ; p++) { mpfr_set_prec (x, p); for (n = 0 ; n < nmax ; n++) { mpfr_urandomb (x, RANDS); mpq_set_ui (y, randlimb (), randlimb() ); if (!MPFR_IS_SINGULAR (x)) { mpfr_sub_q (z, x, y, MPFR_RNDN); res1 = mpfr_sgn (z); res2 = mpfr_cmp_q (x, y); if (res1 != res2) { printf("Error for mpfr_cmp_q: res=%d sub_z gives %d\n", res2, res1); exit (1); } } } } mpq_clear (y); mpfr_clear (x); mpfr_clear (z); }
static void special (void) { mpfr_t x, y; mpq_t q; mpz_t z; int res = 0; mpfr_init (x); mpfr_init (y); mpq_init (q); mpz_init (z); /* cancellation in mpfr_add_q */ mpfr_set_prec (x, 60); mpfr_set_prec (y, 20); mpz_set_str (mpq_numref (q), "-187207494", 10); mpz_set_str (mpq_denref (q), "5721", 10); mpfr_set_str_binary (x, "11111111101001011011100101100011011110010011100010000100001E-44"); mpfr_add_q (y, x, q, MPFR_RNDN); CHECK_FOR ("cancelation in add_q", mpfr_cmp_ui_2exp (y, 256783, -64) == 0); mpfr_set_prec (x, 19); mpfr_set_str_binary (x, "0.1011110101110011100E0"); mpz_set_str (mpq_numref (q), "187207494", 10); mpz_set_str (mpq_denref (q), "5721", 10); mpfr_set_prec (y, 29); mpfr_add_q (y, x, q, MPFR_RNDD); mpfr_set_prec (x, 29); mpfr_set_str_binary (x, "11111111101001110011010001001E-14"); CHECK_FOR ("cancelation in add_q", mpfr_cmp (x,y) == 0); /* Inf */ mpfr_set_inf (x, 1); mpz_set_str (mpq_numref (q), "395877315", 10); mpz_set_str (mpq_denref (q), "3508975966", 10); mpfr_set_prec (y, 118); mpfr_add_q (y, x, q, MPFR_RNDU); CHECK_FOR ("inf", mpfr_inf_p (y) && mpfr_sgn (y) > 0); mpfr_sub_q (y, x, q, MPFR_RNDU); CHECK_FOR ("inf", mpfr_inf_p (y) && mpfr_sgn (y) > 0); /* Nan */ MPFR_SET_NAN (x); mpfr_add_q (y, x, q, MPFR_RNDU); CHECK_FOR ("nan", mpfr_nan_p (y)); mpfr_sub_q (y, x, q, MPFR_RNDU); CHECK_FOR ("nan", mpfr_nan_p (y)); /* Exact value */ mpfr_set_prec (x, 60); mpfr_set_prec (y, 60); mpfr_set_str1 (x, "0.5"); mpz_set_str (mpq_numref (q), "3", 10); mpz_set_str (mpq_denref (q), "2", 10); res = mpfr_add_q (y, x, q, MPFR_RNDU); CHECK_FOR ("0.5+3/2", mpfr_cmp_ui(y, 2)==0 && res==0); res = mpfr_sub_q (y, x, q, MPFR_RNDU); CHECK_FOR ("0.5-3/2", mpfr_cmp_si(y, -1)==0 && res==0); /* Inf Rationnal */ mpq_set_ui (q, 1, 0); mpfr_set_str1 (x, "0.5"); res = mpfr_add_q (y, x, q, MPFR_RNDN); CHECK_FOR ("0.5+1/0", mpfr_inf_p (y) && MPFR_IS_POS (y) && res == 0); res = mpfr_sub_q (y, x, q, MPFR_RNDN); CHECK_FOR ("0.5-1/0", mpfr_inf_p (y) && MPFR_IS_NEG (y) && res == 0); mpq_set_si (q, -1, 0); res = mpfr_add_q (y, x, q, MPFR_RNDN); CHECK_FOR ("0.5+ -1/0", mpfr_inf_p (y) && MPFR_IS_NEG (y) && res == 0); res = mpfr_sub_q (y, x, q, MPFR_RNDN); CHECK_FOR ("0.5- -1/0", mpfr_inf_p (y) && MPFR_IS_POS (y) && res == 0); res = mpfr_div_q (y, x, q, MPFR_RNDN); CHECK_FOR ("0.5 / (-1/0)", mpfr_zero_p (y) && MPFR_IS_NEG (y) && res == 0); mpq_set_ui (q, 1, 0); mpfr_set_inf (x, 1); res = mpfr_add_q (y, x, q, MPFR_RNDN); CHECK_FOR ("+Inf + +Inf", mpfr_inf_p (y) && MPFR_IS_POS (y) && res == 0); res = mpfr_sub_q (y, x, q, MPFR_RNDN); CHECK_FOR ("+Inf - +Inf", MPFR_IS_NAN (y) && res == 0); mpfr_set_inf (x, -1); res = mpfr_add_q (y, x, q, MPFR_RNDN); CHECK_FOR ("-Inf + +Inf", MPFR_IS_NAN (y) && res == 0); res = mpfr_sub_q (y, x, q, MPFR_RNDN); CHECK_FOR ("-Inf - +Inf", mpfr_inf_p (y) && MPFR_IS_NEG (y) && res == 0); mpq_set_si (q, -1, 0); mpfr_set_inf (x, 1); res = mpfr_add_q (y, x, q, MPFR_RNDN); CHECK_FOR ("+Inf + -Inf", MPFR_IS_NAN (y) && res == 0); res = mpfr_sub_q (y, x, q, MPFR_RNDN); CHECK_FOR ("+Inf - -Inf", mpfr_inf_p (y) && MPFR_IS_POS (y) && res == 0); mpfr_set_inf (x, -1); res = mpfr_add_q (y, x, q, MPFR_RNDN); CHECK_FOR ("-Inf + -Inf", mpfr_inf_p (y) && MPFR_IS_NEG (y) && res == 0); res = mpfr_sub_q (y, x, q, MPFR_RNDN); CHECK_FOR ("-Inf - -Inf", MPFR_IS_NAN (y) && res == 0); /* 0 */ mpq_set_ui (q, 0, 1); mpfr_set_ui (x, 42, MPFR_RNDN); res = mpfr_add_q (y, x, q, MPFR_RNDN); CHECK_FOR ("42+0/1", mpfr_cmp_ui (y, 42) == 0 && res == 0); res = mpfr_sub_q (y, x, q, MPFR_RNDN); CHECK_FOR ("42-0/1", mpfr_cmp_ui (y, 42) == 0 && res == 0); res = mpfr_mul_q (y, x, q, MPFR_RNDN); CHECK_FOR ("42*0/1", mpfr_zero_p (y) && MPFR_IS_POS (y) && res == 0); mpfr_clear_flags (); res = mpfr_div_q (y, x, q, MPFR_RNDN); CHECK_FOR ("42/(0/1)", mpfr_inf_p (y) && MPFR_IS_POS (y) && res == 0 && mpfr_divby0_p ()); mpz_set_ui (z, 0); mpfr_clear_flags (); res = mpfr_div_z (y, x, z, MPFR_RNDN); CHECK_FORZ ("42/0", mpfr_inf_p (y) && MPFR_IS_POS (y) && res == 0 && mpfr_divby0_p ()); mpz_clear (z); mpq_clear (q); mpfr_clear (x); mpfr_clear (y); }
static void check_for_zero (void) { /* Check that 0 is unsigned! */ mpq_t q; mpz_t z; mpfr_t x; int r; mpfr_sign_t i; mpfr_init (x); mpz_init (z); mpq_init (q); mpz_set_ui (z, 0); mpq_set_ui (q, 0, 1); MPFR_SET_ZERO (x); RND_LOOP (r) { for (i = MPFR_SIGN_NEG ; i <= MPFR_SIGN_POS ; i+=MPFR_SIGN_POS-MPFR_SIGN_NEG) { MPFR_SET_SIGN(x, i); mpfr_add_z (x, x, z, (mpfr_rnd_t) r); if (!MPFR_IS_ZERO(x) || MPFR_SIGN(x)!=i) { printf("GMP Zero errors for add_z & rnd=%s & s=%d\n", mpfr_print_rnd_mode ((mpfr_rnd_t) r), i); mpfr_dump (x); exit (1); } mpfr_sub_z (x, x, z, (mpfr_rnd_t) r); if (!MPFR_IS_ZERO(x) || MPFR_SIGN(x)!=i) { printf("GMP Zero errors for sub_z & rnd=%s & s=%d\n", mpfr_print_rnd_mode ((mpfr_rnd_t) r), i); mpfr_dump (x); exit (1); } mpfr_mul_z (x, x, z, (mpfr_rnd_t) r); if (!MPFR_IS_ZERO(x) || MPFR_SIGN(x)!=i) { printf("GMP Zero errors for mul_z & rnd=%s & s=%d\n", mpfr_print_rnd_mode ((mpfr_rnd_t) r), i); mpfr_dump (x); exit (1); } mpfr_add_q (x, x, q, (mpfr_rnd_t) r); if (!MPFR_IS_ZERO(x) || MPFR_SIGN(x)!=i) { printf("GMP Zero errors for add_q & rnd=%s & s=%d\n", mpfr_print_rnd_mode ((mpfr_rnd_t) r), i); mpfr_dump (x); exit (1); } mpfr_sub_q (x, x, q, (mpfr_rnd_t) r); if (!MPFR_IS_ZERO(x) || MPFR_SIGN(x)!=i) { printf("GMP Zero errors for sub_q & rnd=%s & s=%d\n", mpfr_print_rnd_mode ((mpfr_rnd_t) r), i); mpfr_dump (x); exit (1); } } } mpq_clear (q); mpz_clear (z); mpfr_clear (x); }
static void addsubq_overflow_aux (mpfr_exp_t e) { mpfr_t x, y; mpq_t q; mpfr_exp_t emax; int inex; int rnd; int sign, sub; MPFR_ASSERTN (e <= LONG_MAX); emax = mpfr_get_emax (); set_emax (e); mpfr_inits2 (16, x, y, (mpfr_ptr) 0); mpq_init (q); mpfr_set_inf (x, 1); mpfr_nextbelow (x); mpq_set_ui (q, 1, 1); for (sign = 0; sign <= 1; sign++) { for (sub = 0; sub <= 1; sub++) { RND_LOOP(rnd) { unsigned int flags, ex_flags; int inf; inf = rnd == MPFR_RNDA || rnd == (sign ? MPFR_RNDD : MPFR_RNDU); ex_flags = MPFR_FLAGS_INEXACT | (inf ? MPFR_FLAGS_OVERFLOW : 0); mpfr_clear_flags (); inex = sub ? mpfr_sub_q (y, x, q, (mpfr_rnd_t) rnd) : mpfr_add_q (y, x, q, (mpfr_rnd_t) rnd); flags = __gmpfr_flags; if (inex == 0 || flags != ex_flags || (inf ? ! mpfr_inf_p (y) : ! mpfr_equal_p (x, y))) { printf ("Error in addsubq_overflow_aux(%ld)," " sign = %d, %s\n", (long) e, sign, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); printf ("Got inex = %d, y = ", inex); mpfr_dump (y); printf ("Expected flags:"); flags_out (ex_flags); printf ("Got flags: "); flags_out (flags); exit (1); } } mpq_neg (q, q); } mpfr_neg (x, x, MPFR_RNDN); mpq_neg (q, q); } mpq_clear (q); mpfr_clears (x, y, (mpfr_ptr) 0); set_emax (emax); }
static void reduced_expo_range (void) { mpfr_t x; mpz_t z; mpq_t q; mpfr_exp_t emin; int inex; emin = mpfr_get_emin (); set_emin (4); mpfr_init2 (x, 32); mpz_init (z); mpfr_clear_flags (); inex = mpfr_set_ui (x, 17, MPFR_RNDN); MPFR_ASSERTN (inex == 0); mpz_set_ui (z, 3); inex = mpfr_mul_z (x, x, z, MPFR_RNDN); if (inex != 0 || MPFR_IS_NAN (x) || mpfr_cmp_ui (x, 51) != 0) { printf ("Error 1 in reduce_expo_range: expected 51 with inex = 0," " got\n"); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); printf ("with inex = %d\n", inex); exit (1); } inex = mpfr_div_z (x, x, z, MPFR_RNDN); if (inex != 0 || MPFR_IS_NAN (x) || mpfr_cmp_ui (x, 17) != 0) { printf ("Error 2 in reduce_expo_range: expected 17 with inex = 0," " got\n"); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); printf ("with inex = %d\n", inex); exit (1); } inex = mpfr_add_z (x, x, z, MPFR_RNDN); if (inex != 0 || MPFR_IS_NAN (x) || mpfr_cmp_ui (x, 20) != 0) { printf ("Error 3 in reduce_expo_range: expected 20 with inex = 0," " got\n"); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); printf ("with inex = %d\n", inex); exit (1); } inex = mpfr_sub_z (x, x, z, MPFR_RNDN); if (inex != 0 || MPFR_IS_NAN (x) || mpfr_cmp_ui (x, 17) != 0) { printf ("Error 4 in reduce_expo_range: expected 17 with inex = 0," " got\n"); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); printf ("with inex = %d\n", inex); exit (1); } MPFR_ASSERTN (__gmpfr_flags == 0); if (mpfr_cmp_z (x, z) <= 0) { printf ("Error 5 in reduce_expo_range: expected a positive value.\n"); exit (1); } mpz_clear (z); mpq_init (q); mpq_set_ui (q, 1, 1); mpfr_set_ui (x, 16, MPFR_RNDN); inex = mpfr_add_q (x, x, q, MPFR_RNDN); if (inex != 0 || MPFR_IS_NAN (x) || mpfr_cmp_ui (x, 17) != 0) { printf ("Error in reduce_expo_range for 16 + 1/1," " got inex = %d and\nx = ", inex); mpfr_dump (x); exit (1); } inex = mpfr_sub_q (x, x, q, MPFR_RNDN); if (inex != 0 || MPFR_IS_NAN (x) || mpfr_cmp_ui (x, 16) != 0) { printf ("Error in reduce_expo_range for 17 - 1/1," " got inex = %d and\nx = ", inex); mpfr_dump (x); exit (1); } mpq_clear (q); mpfr_clear (x); set_emin (emin); }
static PyObject * GMPy_Real_Sub(PyObject *x, PyObject *y, CTXT_Object *context) { MPFR_Object *result; CHECK_CONTEXT(context); if (!(result = GMPy_MPFR_New(0, context))) return NULL; /* This only processes mpfr if the exponent is still in-bounds. Need * to handle the rare case at the end. */ if (MPFR_Check(x) && MPFR_Check(y)) { mpfr_clear_flags(); result->rc = mpfr_sub(result->f, MPFR(x), MPFR(y), GET_MPFR_ROUND(context)); goto done; } if (MPFR_Check(x)) { if (PyIntOrLong_Check(y)) { int error; long temp = GMPy_Integer_AsLongAndError(y, &error); if (!error) { mpfr_clear_flags(); result->rc = mpfr_sub_si(result->f, MPFR(x), temp, GET_MPFR_ROUND(context)); goto done; } else { mpz_t tempz; mpz_inoc(tempz); mpz_set_PyIntOrLong(tempz, y); mpfr_clear_flags(); result->rc = mpfr_sub_z(result->f, MPFR(x), tempz, GET_MPFR_ROUND(context)); mpz_cloc(tempz); goto done; } } if (CHECK_MPZANY(y)) { mpfr_clear_flags(); result->rc = mpfr_sub_z(result->f, MPFR(x), MPZ(y), GET_MPFR_ROUND(context)); goto done; } if (IS_RATIONAL(y)) { MPQ_Object *tempy; if (!(tempy = GMPy_MPQ_From_Number(y, context))) { Py_DECREF((PyObject*)result); return NULL; } mpfr_clear_flags(); result->rc = mpfr_sub_q(result->f, MPFR(x), tempy->q, GET_MPFR_ROUND(context)); Py_DECREF((PyObject*)tempy); goto done; } if (PyFloat_Check(y)) { mpfr_clear_flags(); result->rc = mpfr_sub_d(result->f, MPFR(x), PyFloat_AS_DOUBLE(y), GET_MPFR_ROUND(context)); goto done; } } if (MPFR_Check(y)) { if (PyIntOrLong_Check(x)) { int error; long temp = GMPy_Integer_AsLongAndError(x, &error); if (!error) { mpfr_clear_flags(); result->rc = mpfr_sub_si(result->f, MPFR(y), temp, GET_MPFR_ROUND(context)); mpfr_neg(result->f, result->f, GET_MPFR_ROUND(context)); goto done; } else { mpz_t tempz; mpz_inoc(tempz); mpz_set_PyIntOrLong(tempz, x); mpfr_clear_flags(); result->rc = mpfr_sub_z(result->f, MPFR(y), tempz, GET_MPFR_ROUND(context)); mpfr_neg(result->f, result->f, GET_MPFR_ROUND(context)); mpz_cloc(tempz); goto done; } } if (CHECK_MPZANY(x)) { mpfr_clear_flags(); result->rc = mpfr_sub_z(result->f, MPFR(y), MPZ(x), GET_MPFR_ROUND(context)); mpfr_neg(result->f, result->f, GET_MPFR_ROUND(context)); goto done; } if (IS_RATIONAL(x)) { MPQ_Object *tempx; if (!(tempx = GMPy_MPQ_From_Number(x, context))) { Py_DECREF((PyObject*)result); return NULL; } mpfr_clear_flags(); result->rc = mpfr_sub_q(result->f, MPFR(y), tempx->q, GET_MPFR_ROUND(context)); mpfr_neg(result->f, result->f, GET_MPFR_ROUND(context)); Py_DECREF((PyObject*)tempx); goto done; } if (PyFloat_Check(x)) { mpfr_clear_flags(); result->rc = mpfr_sub_d(result->f, MPFR(y), PyFloat_AS_DOUBLE(x), GET_MPFR_ROUND(context)); mpfr_neg(result->f, result->f, GET_MPFR_ROUND(context)); goto done; } } if (IS_REAL(x) && IS_REAL(y)) { MPFR_Object *tempx, *tempy; tempx = GMPy_MPFR_From_Real(x, 1, context); tempy = GMPy_MPFR_From_Real(y, 1, context); if (!tempx || !tempy) { Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)result); return NULL; } mpfr_clear_flags(); result->rc = mpfr_sub(result->f, MPFR(tempx), MPFR(tempy), GET_MPFR_ROUND(context)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); goto done; } Py_DECREF((PyObject*)result); Py_RETURN_NOTIMPLEMENTED; done: GMPY_MPFR_CLEANUP(result, context, "subtraction"); return (PyObject*)result; }