Annotation of OpenXM_contrib/gmp/mpf/set_q.c, Revision 1.1.1.2
1.1 maekawa 1: /* mpf_set_q (mpf_t rop, mpq_t op) -- Convert the rational op to the float rop.
2:
1.1.1.2 ! maekawa 3: Copyright (C) 1996, 1999 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_set_q (mpf_t r, mpq_srcptr q)
29: #else
30: mpf_set_q (r, q)
31: mpf_t r;
32: mpq_srcptr q;
33: #endif
34: {
35: mp_ptr np, dp;
36: mp_ptr rp;
37: mp_size_t nsize, dsize;
38: mp_size_t qsize, rsize;
39: mp_size_t sign_quotient;
40: unsigned normalization_steps;
41: mp_limb_t qlimb;
42: mp_ptr qp;
43: mp_size_t prec;
44: mp_exp_t exp;
45: TMP_DECL (marker);
46:
47: nsize = SIZ (&q->_mp_num);
48: dsize = SIZ (&q->_mp_den);
49:
50: if (nsize == 0)
51: {
52: SIZ (r) = 0;
53: EXP (r) = 0;
54: return;
55: }
56:
57: prec = PREC (r) + 1;
58:
59: TMP_MARK (marker);
60:
61: qp = PTR (r);
62:
63: sign_quotient = nsize ^ dsize;
64: nsize = ABS (nsize);
65: dsize = ABS (dsize);
66: np = PTR (&q->_mp_num);
67: dp = PTR (&q->_mp_den);
68:
69: exp = nsize - dsize;
70:
71: if (nsize > prec)
72: {
73: np += nsize - prec;
74: nsize = prec;
75: }
76: if (dsize > prec)
77: {
78: dp += dsize - prec;
79: dsize = prec;
80: }
81:
82: rsize = MAX (nsize, dsize);
83: rp = (mp_ptr) TMP_ALLOC ((rsize + 1) * BYTES_PER_MP_LIMB);
84:
85: count_leading_zeros (normalization_steps, dp[dsize - 1]);
86:
87: /* Normalize the denominator, i.e. make its most significant bit set by
88: shifting it NORMALIZATION_STEPS bits to the left. Also shift the
89: numerator the same number of steps (to keep the quotient the same!). */
90: if (normalization_steps != 0)
91: {
92: mp_ptr tp;
93: mp_limb_t nlimb;
94:
95: /* Shift up the denominator setting the most significant bit of
96: the most significant limb. Use temporary storage not to clobber
97: the original contents of the denominator. */
98: tp = (mp_ptr) TMP_ALLOC (dsize * BYTES_PER_MP_LIMB);
99: mpn_lshift (tp, dp, dsize, normalization_steps);
100: dp = tp;
101:
102: if (rsize != nsize)
103: {
104: MPN_ZERO (rp, rsize - nsize);
105: nlimb = mpn_lshift (rp + (rsize - nsize),
106: np, nsize, normalization_steps);
107: }
108: else
109: {
1.1.1.2 ! maekawa 110: nlimb = mpn_lshift (rp, np, rsize, normalization_steps);
1.1 maekawa 111: }
112: if (nlimb != 0)
113: {
114: rp[rsize] = nlimb;
115: exp++;
1.1.1.2 ! maekawa 116: /* Don't just increase rsize, chop off rp at the low end instead. */
! 117: if (rsize == prec)
! 118: rp++;
! 119: else
! 120: rsize++;
1.1 maekawa 121: }
122: }
123: else
124: {
125: if (rsize != nsize)
126: {
127: MPN_ZERO (rp, rsize - nsize);
128: MPN_COPY (rp + (rsize - nsize), np, nsize);
129: }
130: else
131: {
132: MPN_COPY (rp, np, rsize);
133: }
134: }
135:
136: qlimb = mpn_divrem (qp, prec - 1 - (rsize - dsize), rp, rsize, dp, dsize);
137: qsize = prec - 1;
138: if (qlimb)
139: {
140: qp[qsize] = qlimb;
141: qsize++;
142: exp++;
143: }
144:
145: EXP (r) = exp;
1.1.1.2 ! maekawa 146: SIZ (r) = sign_quotient >= 0 ? qsize : -qsize;
1.1 maekawa 147:
148: TMP_FREE (marker);
149: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>