1 /* Reference floating point routines.
3 Copyright (C) 1996 Free Software Foundation, Inc.
5 This file is part of the GNU MP Library.
7 The GNU MP Library is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Library General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or (at your
10 option) any later version.
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
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
15 License for more details.
17 You should have received a copy of the GNU Library General Public License
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. */
26 void ref_mpf_add (mpf_t, const mpf_t, const mpf_t);
27 void ref_mpf_sub (mpf_t, const mpf_t, const mpf_t);
35 ref_mpf_add (mpf_t w, const mpf_t u, const mpf_t v)
43 mp_size_t hi, lo, size;
55 wt = (mp_ptr) TMP_ALLOC (size * BYTES_PER_MP_LIMB);
56 MPN_COPY (wt, PTR (v), size);
64 wt = (mp_ptr) TMP_ALLOC (size * BYTES_PER_MP_LIMB);
65 MPN_COPY (wt, PTR (u), size);
70 if ((SIZ (u) ^ SIZ (v)) < 0)
76 ref_mpf_sub (w, u, tmp);
81 /* Compute the significance of the hi and lo end of the result. */
82 hi = MAX (EXP (u), EXP (v));
83 lo = MIN (EXP (u) - ABSIZ (u), EXP (v) - ABSIZ (v));
85 ut = (mp_ptr) TMP_ALLOC ((size + 1) * BYTES_PER_MP_LIMB);
86 vt = (mp_ptr) TMP_ALLOC ((size + 1) * BYTES_PER_MP_LIMB);
87 wt = (mp_ptr) TMP_ALLOC ((size + 1) * BYTES_PER_MP_LIMB);
91 off = size + (EXP (u) - hi) - ABSIZ (u);
92 MPN_COPY (ut + off, PTR (u), ABSIZ (u));
93 off = size + (EXP (v) - hi) - ABSIZ (v);
94 MPN_COPY (vt + off, PTR (v), ABSIZ (v));
97 cy = mpn_add_n (wt, ut, vt, size);
105 wt += size - PREC (w);
108 MPN_COPY (PTR (w), wt, size);
109 SIZ (w) = neg == 0 ? size : -size;
116 ref_mpf_sub (mpf_t w, const mpf_t u, const mpf_t v)
118 ref_mpf_sub (w, u, v)
124 mp_size_t hi, lo, size;
135 wt = (mp_ptr) TMP_ALLOC (size * BYTES_PER_MP_LIMB);
136 MPN_COPY (wt, PTR (v), size);
144 wt = (mp_ptr) TMP_ALLOC (size * BYTES_PER_MP_LIMB);
145 MPN_COPY (wt, PTR (u), size);
150 if ((SIZ (u) ^ SIZ (v)) < 0)
153 SIZ (tmp) = -SIZ (v);
156 ref_mpf_add (w, u, tmp);
163 /* Compute the significance of the hi and lo end of the result. */
164 hi = MAX (EXP (u), EXP (v));
165 lo = MIN (EXP (u) - ABSIZ (u), EXP (v) - ABSIZ (v));
167 ut = (mp_ptr) TMP_ALLOC ((size + 1) * BYTES_PER_MP_LIMB);
168 vt = (mp_ptr) TMP_ALLOC ((size + 1) * BYTES_PER_MP_LIMB);
169 wt = (mp_ptr) TMP_ALLOC ((size + 1) * BYTES_PER_MP_LIMB);
173 off = size + (EXP (u) - hi) - ABSIZ (u);
174 MPN_COPY (ut + off, PTR (u), ABSIZ (u));
175 off = size + (EXP (v) - hi) - ABSIZ (v);
176 MPN_COPY (vt + off, PTR (v), ABSIZ (v));
179 if (mpn_cmp (ut, vt, size) >= 0)
180 mpn_sub_n (wt, ut, vt, size);
183 mpn_sub_n (wt, vt, ut, size);
187 while (size != 0 && wt[size - 1] == 0)
196 wt += size - PREC (w);
199 MPN_COPY (PTR (w), wt, size);
200 SIZ (w) = neg == 0 ? size : -size;