Annotation of OpenXM_contrib/gmp/mpq/md_2exp.c, Revision 1.1.1.1
1.1 ohara 1: /* mpq_mul_2exp, mpq_div_2exp - multiply or divide by 2^N */
2:
3: /*
4: Copyright 2000, 2002 Free Software Foundation, Inc.
5:
6: This file is part of the GNU MP Library.
7:
8: The GNU MP Library is free software; you can redistribute it and/or modify
9: it under the terms of the GNU Lesser General Public License as published by
10: the Free Software Foundation; either version 2.1 of the License, or (at your
11: option) any later version.
12:
13: The GNU MP Library is distributed in the hope that it will be useful, but
14: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15: or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16: License for more details.
17:
18: You should have received a copy of the GNU Lesser General Public License
19: along with the GNU MP Library; see the file COPYING.LIB. If not, write to
20: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21: MA 02111-1307, USA.
22: */
23:
24: #include "gmp.h"
25: #include "gmp-impl.h"
26: #include "longlong.h"
27:
28:
29: /* The multiplier/divisor "n", representing 2^n, is applied by right shifting
30: "r" until it's odd (if it isn't already), and left shifting "l" for the
31: rest. */
32:
33: static void
34: mord_2exp (mpz_ptr ldst, mpz_ptr rdst, mpz_srcptr lsrc, mpz_srcptr rsrc,
35: unsigned long n)
36: {
37: mp_size_t rsrc_size = SIZ(rsrc);
38: mp_size_t len = ABS (rsrc_size);
39: mp_ptr rsrc_ptr = PTR(rsrc);
40: mp_ptr p, rdst_ptr;
41: mp_limb_t plow;
42:
43: p = rsrc_ptr;
44: plow = *p;
45: while (n >= GMP_NUMB_BITS && plow == 0)
46: {
47: n -= GMP_NUMB_BITS;
48: p++;
49: plow = *p;
50: }
51:
52: /* no realloc here if rsrc==rdst, so p and rsrc_ptr remain valid */
53: len -= (p - rsrc_ptr);
54: MPZ_REALLOC (rdst, len);
55: rdst_ptr = PTR(rdst);
56:
57: if ((plow & 1) || n == 0)
58: {
59: /* need DECR when src==dst */
60: if (p != rdst_ptr)
61: MPN_COPY_DECR (rdst_ptr, p, len);
62: }
63: else
64: {
65: unsigned long shift;
66: if (plow == 0)
67: shift = n;
68: else
69: {
70: count_trailing_zeros (shift, plow);
71: shift = MIN (shift, n);
72: }
73: mpn_rshift (rdst_ptr, p, len, shift);
74: len -= (rdst_ptr[len-1] == 0);
75: n -= shift;
76: }
77: SIZ(rdst) = (rsrc_size >= 0) ? len : -len;
78:
79: if (n)
80: mpz_mul_2exp (ldst, lsrc, n);
81: else if (ldst != lsrc)
82: mpz_set (ldst, lsrc);
83: }
84:
85:
86: void
87: mpq_mul_2exp (mpq_ptr dst, mpq_srcptr src, unsigned long n)
88: {
89: mord_2exp (mpq_numref (dst), mpq_denref (dst),
90: mpq_numref (src), mpq_denref (src), n);
91: }
92:
93: void
94: mpq_div_2exp (mpq_ptr dst, mpq_srcptr src, unsigned long n)
95: {
96: if (SIZ (mpq_numref(src)) == 0)
97: {
98: dst->_mp_num._mp_size = 0;
99: dst->_mp_den._mp_size = 1;
100: dst->_mp_den._mp_d[0] = 1;
101: return;
102: }
103:
104: mord_2exp (mpq_denref (dst), mpq_numref (dst),
105: mpq_denref (src), mpq_numref (src), n);
106: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>