summaryrefslogtreecommitdiff
path: root/src/sqr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sqr.c')
-rw-r--r--src/sqr.c146
1 files changed, 0 insertions, 146 deletions
diff --git a/src/sqr.c b/src/sqr.c
index b5be792..a1699e3 100644
--- a/src/sqr.c
+++ b/src/sqr.c
@@ -21,152 +21,6 @@ along with this program. If not, see http://www.gnu.org/licenses/ .
#include <stdio.h> /* for MPC_ASSERT */
#include "mpc-impl.h"
-#define mpz_add_si(z,x,y) do { \
- if (y >= 0) \
- mpz_add_ui (z, x, (long int) y); \
- else \
- mpz_sub_ui (z, x, (long int) (-y)); \
- } while (0);
-
-static int
-mpfr_fmma (mpfr_ptr z, mpfr_srcptr a, mpfr_srcptr b, mpfr_srcptr c,
- mpfr_srcptr d, int sign, mpfr_rnd_t rnd)
-{
- /* Computes z = ab+cd if sign >= 0, or z = ab-cd if sign < 0.
- Assumes that a, b, c, d are finite and non-zero; so any multiplication
- of two of them yielding an infinity is an overflow, and a
- multiplication yielding 0 is an underflow.
- Assumes further that z is distinct from a, b, c, d. */
-
- int inex;
- mpfr_t u, v;
-
- /* u=a*b, v=sign*c*d exactly */
- mpfr_init2 (u, mpfr_get_prec (a) + mpfr_get_prec (b));
- mpfr_init2 (v, mpfr_get_prec (c) + mpfr_get_prec (d));
- mpfr_mul (u, a, b, GMP_RNDN);
- mpfr_mul (v, c, d, GMP_RNDN);
- if (sign < 0)
- mpfr_neg (v, v, GMP_RNDN);
-
- /* tentatively compute z as u+v; here we need z to be distinct
- from a, b, c, d to not lose the latter */
- inex = mpfr_add (z, u, v, rnd);
-
- if (mpfr_inf_p (z)) {
- /* replace by "correctly rounded overflow" */
- mpfr_set_si (z, (mpfr_signbit (z) ? -1 : 1), GMP_RNDN);
- inex = mpfr_mul_2ui (z, z, mpfr_get_emax (), rnd);
- }
- else if (mpfr_inf_p (u) || mpfr_inf_p (v)
- || mpfr_zero_p (u) || mpfr_zero_p (v)) {
- /* There is at least one over- or underflow.
- Redo the computations with mpz_t exponents */
- mpfr_exp_t ea, eb, ec, ed;
- mpz_t eu, ev;
- /* cheat to work around the const qualifiers */
-
- /* Normalise the input by shifting and keep track of the shifts in
- the exponents of u and v */
- ea = mpfr_get_exp (a);
- eb = mpfr_get_exp (b);
- ec = mpfr_get_exp (c);
- ed = mpfr_get_exp (d);
-
- mpfr_set_exp ((mpfr_ptr) a, (mpfr_prec_t) 0);
- mpfr_set_exp ((mpfr_ptr) b, (mpfr_prec_t) 0);
- mpfr_set_exp ((mpfr_ptr) c, (mpfr_prec_t) 0);
- mpfr_set_exp ((mpfr_ptr) d, (mpfr_prec_t) 0);
-
- mpz_init (eu);
- mpz_init (ev);
- mpz_set_si (eu, (long int) ea);
- mpz_add_si (eu, eu, (long int) eb);
- mpz_set_si (ev, (long int) ec);
- mpz_add_si (ev, ev, (long int) ed);
-
- /* recompute u and v and move exponents to eu and ev */
- mpfr_mul (u, a, b, GMP_RNDN);
- /* exponent of u is non-positive */
- mpz_sub_ui (eu, eu, (unsigned long int) (-mpfr_get_exp (u)));
- mpfr_set_exp (u, (mpfr_prec_t) 0);
- mpfr_mul (v, c, d, GMP_RNDN);
- if (sign < 0)
- mpfr_neg (v, v, GMP_RNDN);
- mpz_sub_ui (ev, ev, (unsigned long int) (-mpfr_get_exp (v)));
- mpfr_set_exp (v, (mpfr_prec_t) 0);
-
- if (mpfr_nan_p (z)) {
- mpfr_exp_t emax = mpfr_get_emax ();
- int overflow;
- /* We have a = ma * 2^ea with 1/2 <= |ma| < 1 and ea <= emax, and
- analogously for b. So eu <= 2*emax, and eu > emax since we have
- an overflow. The same holds for ev. Shift u and v by as much as
- possible so that one of them has exponent emax and the
- remaining exponents in eu and ev are the same. Then carry out
- the addition. Shifting u and v prevents an underflow. */
- if (mpz_cmp (eu, ev) >= 0) {
- mpfr_set_exp (u, emax);
- mpz_sub_ui (eu, eu, (long int) emax);
- mpz_sub (ev, ev, eu);
- mpfr_set_exp (v, (mpfr_exp_t) mpz_get_ui (ev));
- /* remaining common exponent is now in eu */
- }
- else {
- mpfr_set_exp (v, emax);
- mpz_sub_ui (ev, ev, (long int) emax);
- mpz_sub (eu, eu, ev);
- mpfr_set_exp (u, (mpfr_exp_t) mpz_get_ui (eu));
- mpz_set (eu, ev);
- /* remaining common exponent is now also in eu */
- }
- inex = mpfr_add (z, u, v, rnd);
- /* Result is finite since u and v have different signs. */
- overflow = mpfr_mul_2ui (z, z, mpz_get_ui (eu), rnd);
- if (overflow)
- inex = overflow;
- }
- else {
- int underflow;
- /* Addition of two zeroes with same sign. We have a = ma * 2^ea
- with 1/2 <= |ma| < 1 and ea >= emin and similarly for b.
- So 2*emin < 2*emin+1 <= eu < emin < 0, and analogously for v. */
- mpfr_exp_t emin = mpfr_get_emin ();
- if (mpz_cmp (eu, ev) <= 0) {
- mpfr_set_exp (u, emin);
- mpz_add_ui (eu, eu, (unsigned long int) (-emin));
- mpz_sub (ev, ev, eu);
- mpfr_set_exp (v, (mpfr_exp_t) mpz_get_si (ev));
- }
- else {
- mpfr_set_exp (v, emin);
- mpz_add_ui (ev, ev, (unsigned long int) (-emin));
- mpz_sub (eu, eu, ev);
- mpfr_set_exp (u, (mpfr_exp_t) mpz_get_si (eu));
- mpz_set (eu, ev);
- }
- inex = mpfr_add (z, u, v, rnd);
- mpz_neg (eu, eu);
- underflow = mpfr_div_2ui (z, z, mpz_get_ui (eu), rnd);
- if (underflow)
- inex = underflow;
- }
-
- mpz_clear (eu);
- mpz_clear (ev);
-
- mpfr_set_exp ((mpfr_ptr) a, ea);
- mpfr_set_exp ((mpfr_ptr) b, eb);
- mpfr_set_exp ((mpfr_ptr) c, ec);
- mpfr_set_exp ((mpfr_ptr) d, ed);
- /* works also when some of a, b, c, d are not all distinct */
- }
-
- mpfr_clear (u);
- mpfr_clear (v);
-
- return inex;
-}
int
mpc_sqr (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd)