Annotation of OpenXM_contrib/gmp/mpf/div.c, Revision 1.1.1.2
1.1 maekawa 1: /* mpf_div -- Divide two floats.
2:
1.1.1.2 ! maekawa 3: Copyright (C) 1993, 1994, 1996, 2000 Free Software Foundation, Inc.
1.1 maekawa 4:
5: This file is part of the GNU MP Library.
6:
7: The GNU MP Library is free software; you can redistribute it and/or modify
1.1.1.2 ! maekawa 8: it under the terms of the GNU Lesser General Public License as published by
! 9: the Free Software Foundation; either version 2.1 of the License, or (at your
1.1 maekawa 10: option) any later version.
11:
12: The GNU MP Library is distributed in the hope that it will be useful, but
13: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1.1.1.2 ! maekawa 14: or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
1.1 maekawa 15: License for more details.
16:
1.1.1.2 ! maekawa 17: You should have received a copy of the GNU Lesser General Public License
1.1 maekawa 18: along with the GNU MP Library; see the file COPYING.LIB. If not, write to
19: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20: MA 02111-1307, USA. */
21:
22: #include "gmp.h"
23: #include "gmp-impl.h"
24: #include "longlong.h"
25:
26: void
27: #if __STDC__
28: mpf_div (mpf_ptr r, mpf_srcptr u, mpf_srcptr v)
29: #else
30: mpf_div (r, u, v)
31: mpf_ptr r;
32: mpf_srcptr u;
33: mpf_srcptr v;
34: #endif
35: {
36: mp_srcptr up, vp;
37: mp_ptr rp, tp, rtp;
38: mp_size_t usize, vsize;
39: mp_size_t rsize, tsize;
40: mp_size_t sign_quotient;
41: mp_size_t prec;
42: unsigned normalization_steps;
43: mp_limb_t q_limb;
44: mp_exp_t rexp;
45: TMP_DECL (marker);
46:
47: usize = u->_mp_size;
48: vsize = v->_mp_size;
49: sign_quotient = usize ^ vsize;
50: usize = ABS (usize);
51: vsize = ABS (vsize);
52: prec = r->_mp_prec;
53:
54: if (vsize == 0)
1.1.1.2 ! maekawa 55: DIVIDE_BY_ZERO;
! 56:
1.1 maekawa 57: if (usize == 0)
58: {
59: r->_mp_size = 0;
60: r->_mp_exp = 0;
61: return;
62: }
63:
64: TMP_MARK (marker);
65: rexp = u->_mp_exp - v->_mp_exp;
66:
67: rp = r->_mp_d;
68: up = u->_mp_d;
69: vp = v->_mp_d;
70:
71: if (vsize > prec)
72: {
73: vp += vsize - prec;
74: vsize = prec;
75: }
76:
77: tsize = vsize + prec;
78: tp = (mp_ptr) TMP_ALLOC ((tsize + 1) * BYTES_PER_MP_LIMB);
79:
80: if (usize > tsize)
81: {
82: up += usize - tsize;
83: usize = tsize;
84: rtp = tp;
85: }
86: else
87: {
88: MPN_ZERO (tp, tsize - usize);
89: rtp = tp + (tsize - usize);
90: }
91:
92: count_leading_zeros (normalization_steps, vp[vsize - 1]);
93:
94: /* Normalize the divisor and the dividend. */
95: if (normalization_steps != 0)
96: {
97: mp_ptr tmp;
98: mp_limb_t nlimb;
99:
100: /* Shift up the divisor setting the most significant bit of
101: the most significant limb. Use temporary storage not to clobber
102: the original contents of the divisor. */
103: tmp = (mp_ptr) TMP_ALLOC (vsize * BYTES_PER_MP_LIMB);
104: mpn_lshift (tmp, vp, vsize, normalization_steps);
105: vp = tmp;
106:
107: /* Shift up the dividend, possibly introducing a new most
108: significant word. Move the shifted dividend in the remainder
109: at the same time. */
110: nlimb = mpn_lshift (rtp, up, usize, normalization_steps);
111: if (nlimb != 0)
112: {
113: rtp[usize] = nlimb;
114: tsize++;
115: rexp++;
116: }
117: }
118: else
119: {
120: /* The divisor is already normalized, as required.
121: Copy it to temporary space if it overlaps with the quotient. */
122: if (vp - rp <= tsize - vsize)
123: {
124: mp_ptr tmp = (mp_ptr) TMP_ALLOC (vsize * BYTES_PER_MP_LIMB);
125: MPN_COPY (tmp, vp, vsize);
126: vp = (mp_srcptr) tmp;
127: }
128:
129: /* Move the dividend to the remainder. */
130: MPN_COPY (rtp, up, usize);
131: }
132:
133: q_limb = mpn_divmod (rp, tp, tsize, vp, vsize);
134: rsize = tsize - vsize;
135: if (q_limb)
136: {
137: rp[rsize] = q_limb;
138: rsize++;
139: rexp++;
140: }
141:
142: r->_mp_size = sign_quotient >= 0 ? rsize : -rsize;
143: r->_mp_exp = rexp;
144: TMP_FREE (marker);
145: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>