1 /* mpn_sbpi1_divappr_q -- Schoolbook division using the Möller-Granlund 3/2
2 division algorithm, returning approximate quotient. The quotient returned
3 is either correct, or one too large.
5 Contributed to the GNU project by Torbjorn Granlund.
7 THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
8 SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
9 GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GMP RELEASE.
11 Copyright 2007, 2009 Free Software Foundation, Inc.
13 This file is part of the GNU MP Library.
15 The GNU MP Library is free software; you can redistribute it and/or modify
16 it under the terms of the GNU Lesser General Public License as published by
17 the Free Software Foundation; either version 3 of the License, or (at your
18 option) any later version.
20 The GNU MP Library is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
22 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
23 License for more details.
25 You should have received a copy of the GNU Lesser General Public License
26 along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */
34 mpn_sbpi1_divappr_q (mp_ptr qp,
35 mp_ptr np, mp_size_t nn,
36 mp_srcptr dp, mp_size_t dn,
49 ASSERT ((dp[dn-1] & GMP_NUMB_HIGHBIT) != 0);
60 qh = mpn_cmp (np - dn, dp, dn) >= 0;
62 mpn_sub_n (np - dn, np - dn, dp, dn);
66 dn -= 2; /* offset dn by 2 for main division loops,
67 saving two iterations in mpn_submul_1. */
75 for (i = qn - (dn + 2); i >= 0; i--)
78 if (UNLIKELY (n1 == d1) && np[1] == d0)
81 mpn_submul_1 (np - dn, dp, dn + 2, q);
82 n1 = np[1]; /* update n1, last loop's value will now be invalid */
86 udiv_qr_3by2 (q, n1, n0, n1, np[1], np[0], d1, d0, dinv);
88 cy = mpn_submul_1 (np - dn, dp, dn, q);
91 n0 = (n0 - cy) & GMP_NUMB_MASK;
96 if (UNLIKELY (cy != 0))
98 n1 += d1 + mpn_add_n (np - dn, np - dn, dp, dn + 1);
106 flag = ~CNST_LIMB(0);
110 for (i = dn; i > 0; i--)
113 if (UNLIKELY (n1 >= (d1 & flag)))
116 cy = mpn_submul_1 (np - dn, dp, dn + 2, q);
118 if (UNLIKELY (n1 != cy))
120 if (n1 < (cy & flag))
123 mpn_add_n (np - dn, np - dn, dp, dn + 2);
132 udiv_qr_3by2 (q, n1, n0, n1, np[1], np[0], d1, d0, dinv);
134 cy = mpn_submul_1 (np - dn, dp, dn, q);
137 n0 = (n0 - cy) & GMP_NUMB_MASK;
142 if (UNLIKELY (cy != 0))
144 n1 += d1 + mpn_add_n (np - dn, np - dn, dp, dn + 1);
151 /* Truncate operands. */
157 if (UNLIKELY (n1 >= (d1 & flag)))
160 cy = mpn_submul_1 (np, dp, 2, q);
162 if (UNLIKELY (n1 != cy))
164 if (n1 < (cy & flag))
167 add_ssaaaa (np[1], np[0], np[1], np[0], dp[1], dp[0]);
176 udiv_qr_3by2 (q, n1, n0, n1, np[1], np[0], d1, d0, dinv);
185 ASSERT_ALWAYS (np[1] == n1);