Deleted wrongly imported bind sources from base.
[dragonfly.git] / contrib / mpfr / sqr.c
blob439cb266c95315c007a886b5c9c2dabab1eec1ba
1 /* mpfr_sqr -- Floating square
3 Copyright 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
4 Contributed by the Arenaire and Cacao projects, INRIA.
6 This file is part of the GNU MPFR Library.
8 The GNU MPFR Library is free software; you can redistribute
9 it and/or modify it under the terms of the GNU Lesser
10 General Public License as published by the Free Software
11 Foundation; either version 2.1 of the License, or (at your
12 option) any later version.
14 The GNU MPFR Library is distributed in the hope that it will
15 be useful, but WITHOUT ANY WARRANTY; without even the
16 implied warranty of MERCHANTABILITY or FITNESS FOR A
17 PARTICULAR PURPOSE. See the GNU Lesser General Public
18 License for more details.
20 You should have received a copy of the GNU Lesser
21 General Public License along with the GNU MPFR Library; see
22 the file COPYING.LIB. If not, write to the Free Software
23 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
24 MA 02110-1301, USA. */
26 #include "mpfr-impl.h"
28 int
29 mpfr_sqr (mpfr_ptr a, mpfr_srcptr b, mp_rnd_t rnd_mode)
31 int cc, inexact;
32 mp_exp_t ax;
33 mp_limb_t *tmp;
34 mp_limb_t b1;
35 mp_prec_t bq;
36 mp_size_t bn, tn;
37 MPFR_TMP_DECL(marker);
39 MPFR_LOG_FUNC (("x[%#R]=%R rnd=%d", b, b, rnd_mode),
40 ("y[%#R]=%R inexact=%d", a, a, inexact));
42 /* deal with special cases */
43 if (MPFR_UNLIKELY(MPFR_IS_SINGULAR(b)))
45 if (MPFR_IS_NAN(b))
47 MPFR_SET_NAN(a);
48 MPFR_RET_NAN;
50 MPFR_SET_POS (a);
51 if (MPFR_IS_INF(b))
52 MPFR_SET_INF(a);
53 else
54 ( MPFR_ASSERTD(MPFR_IS_ZERO(b)), MPFR_SET_ZERO(a) );
55 MPFR_RET(0);
57 MPFR_CLEAR_FLAGS(a);
58 ax = 2 * MPFR_GET_EXP (b);
59 bq = MPFR_PREC(b);
61 MPFR_ASSERTD (2 * bq > bq); /* PREC_MAX is /2 so no integer overflow */
63 bn = MPFR_LIMB_SIZE(b); /* number of limbs of b */
64 tn = 1 + (2 * bq - 1) / BITS_PER_MP_LIMB; /* number of limbs of square,
65 2*bn or 2*bn-1 */
67 MPFR_TMP_MARK(marker);
68 tmp = (mp_limb_t *) MPFR_TMP_ALLOC((size_t) 2 * bn * BYTES_PER_MP_LIMB);
70 /* Multiplies the mantissa in temporary allocated space */
71 mpn_sqr_n (tmp, MPFR_MANT(b), bn);
72 b1 = tmp[2 * bn - 1];
74 /* now tmp[0]..tmp[2*bn-1] contains the product of both mantissa,
75 with tmp[2*bn-1]>=2^(BITS_PER_MP_LIMB-2) */
76 b1 >>= BITS_PER_MP_LIMB - 1; /* msb from the product */
78 /* if the mantissas of b and c are uniformly distributed in ]1/2, 1],
79 then their product is in ]1/4, 1/2] with probability 2*ln(2)-1 ~ 0.386
80 and in [1/2, 1] with probability 2-2*ln(2) ~ 0.614 */
81 tmp += 2 * bn - tn; /* +0 or +1 */
82 if (MPFR_UNLIKELY(b1 == 0))
83 mpn_lshift (tmp, tmp, tn, 1); /* tn <= k, so no stack corruption */
85 cc = mpfr_round_raw (MPFR_MANT (a), tmp, 2 * bq, 0,
86 MPFR_PREC (a), rnd_mode, &inexact);
87 /* cc = 1 ==> result is a power of two */
88 if (MPFR_UNLIKELY(cc))
89 MPFR_MANT(a)[MPFR_LIMB_SIZE(a)-1] = MPFR_LIMB_HIGHBIT;
91 MPFR_TMP_FREE(marker);
93 mp_exp_t ax2 = ax + (mp_exp_t) (b1 - 1 + cc);
94 if (MPFR_UNLIKELY( ax2 > __gmpfr_emax))
95 return mpfr_overflow (a, rnd_mode, MPFR_SIGN_POS);
96 if (MPFR_UNLIKELY( ax2 < __gmpfr_emin))
98 /* In the rounding to the nearest mode, if the exponent of the exact
99 result (i.e. before rounding, i.e. without taking cc into account)
100 is < __gmpfr_emin - 1 or the exact result is a power of 2 (i.e. if
101 both arguments are powers of 2), then round to zero. */
102 if (rnd_mode == GMP_RNDN &&
103 (ax + (mp_exp_t) b1 < __gmpfr_emin || mpfr_powerof2_raw (b)))
104 rnd_mode = GMP_RNDZ;
105 return mpfr_underflow (a, rnd_mode, MPFR_SIGN_POS);
107 MPFR_SET_EXP (a, ax2);
108 MPFR_SET_POS (a);
110 MPFR_RET (inexact);