summaryrefslogtreecommitdiff
path: root/mpq/div.c
diff options
context:
space:
mode:
authorTorbjorn Granlund <tege@gmplib.org>2008-10-08 19:22:43 +0200
committerTorbjorn Granlund <tege@gmplib.org>2008-10-08 19:22:43 +0200
commitfb57e9b772dccc3b84b974ea7d224e93fe7ed331 (patch)
treefca577f5aba3d49893ae5dc0a5ecfd4c15054384 /mpq/div.c
parent8442a8b9cac73e8af937c4db341967b9e4e92c19 (diff)
downloadgmp-fb57e9b772dccc3b84b974ea7d224e93fe7ed331.tar.gz
Use TMP_ALLOC. Cleanup.
Diffstat (limited to 'mpq/div.c')
-rw-r--r--mpq/div.c64
1 files changed, 46 insertions, 18 deletions
diff --git a/mpq/div.c b/mpq/div.c
index 8e3bc37f0..efba32a2f 100644
--- a/mpq/div.c
+++ b/mpq/div.c
@@ -27,20 +27,52 @@ mpq_div (mpq_ptr quot, mpq_srcptr op1, mpq_srcptr op2)
mpz_t gcd1, gcd2;
mpz_t tmp1, tmp2;
mpz_t numtmp;
-
- if (op2->_mp_num._mp_size == 0)
+ mp_size_t op1_num_size;
+ mp_size_t op1_den_size;
+ mp_size_t op2_num_size;
+ mp_size_t op2_den_size;
+ mp_size_t alloc;
+ TMP_DECL;
+
+ op1_num_size = ABS (op1->_mp_num._mp_size);
+ op1_den_size = op1->_mp_den._mp_size;
+ op2_num_size = ABS (op2->_mp_num._mp_size);
+ op2_den_size = op2->_mp_den._mp_size;
+
+ if (op2_num_size == 0)
DIVIDE_BY_ZERO;
- mpz_init (gcd1);
- mpz_init (gcd2);
- mpz_init (tmp1);
- mpz_init (tmp2);
- mpz_init (numtmp);
+ if (op1_num_size == 0)
+ {
+ /* We special case this to simplify allocation logic; gcd(0,x) = x
+ is a singular case for the allocations. */
+ quot->_mp_num._mp_size = 0;
+ quot->_mp_den._mp_d[0] = 1;
+ quot->_mp_den._mp_size = 1;
+ return;
+ }
+
+ TMP_MARK;
+
+ alloc = MIN (op1_num_size, op2_num_size);
+ MPZ_TMP_INIT (gcd1, alloc);
+
+ alloc = MIN (op1_den_size, op2_den_size);
+ MPZ_TMP_INIT (gcd2, alloc);
+
+ alloc = MAX (op1_num_size, op2_num_size);
+ MPZ_TMP_INIT (tmp1, alloc);
+
+ alloc = MAX (op1_den_size, op2_den_size);
+ MPZ_TMP_INIT (tmp2, alloc);
+
+ alloc = op1_num_size + op2_den_size;
+ MPZ_TMP_INIT (numtmp, alloc);
- /* QUOT might be identical to either operand, so don't store the
- result there until we are finished with the input operands. We
- dare to overwrite the numerator of QUOT when we are finished
- with the numerators of OP1 and OP2. */
+ /* QUOT might be identical to either operand, so don't store the result there
+ until we are finished with the input operands. We can overwrite the
+ numerator of QUOT when we are finished with the numerators of OP1 and
+ OP2. */
mpz_gcd (gcd1, &(op1->_mp_num), &(op2->_mp_num));
mpz_gcd (gcd2, &(op2->_mp_den), &(op1->_mp_den));
@@ -55,8 +87,8 @@ mpq_div (mpq_ptr quot, mpq_srcptr op1, mpq_srcptr op2)
mpz_mul (&(quot->_mp_den), tmp1, tmp2);
- /* We needed to go via NUMTMP to take care of QUOT being the same
- as either input operands. Now move NUMTMP to QUOT->_mp_num. */
+ /* We needed to go via NUMTMP to take care of QUOT being the same as OP2.
+ Now move NUMTMP to QUOT->_mp_num. */
mpz_set (&(quot->_mp_num), numtmp);
/* Keep the denominator positive. */
@@ -66,9 +98,5 @@ mpq_div (mpq_ptr quot, mpq_srcptr op1, mpq_srcptr op2)
quot->_mp_num._mp_size = -quot->_mp_num._mp_size;
}
- mpz_clear (numtmp);
- mpz_clear (tmp2);
- mpz_clear (tmp1);
- mpz_clear (gcd2);
- mpz_clear (gcd1);
+ TMP_FREE;
}