diff options
author | tege <tege@gmplib.org> | 1999-03-14 01:44:22 +0100 |
---|---|---|
committer | tege <tege@gmplib.org> | 1999-03-14 01:44:22 +0100 |
commit | 033ba933aef8bee6739ae3e7979182a127a306f0 (patch) | |
tree | 805bbfd532c861d96a94deef34c11f799659658b /mpf | |
parent | 8e021d9735bbef876c08bfff9a2e33d491f7bcd5 (diff) | |
download | gmp-033ba933aef8bee6739ae3e7979182a127a306f0.tar.gz |
* Set result sign.
* When normalizing the numerator, don't allow it to increase in size beyond
prec.
Diffstat (limited to 'mpf')
-rw-r--r-- | mpf/set_q.c | 35 |
1 files changed, 7 insertions, 28 deletions
diff --git a/mpf/set_q.c b/mpf/set_q.c index 69d81e33e..1327abb1d 100644 --- a/mpf/set_q.c +++ b/mpf/set_q.c @@ -23,31 +23,6 @@ MA 02111-1307, USA. */ #include "gmp-impl.h" #include "longlong.h" -/* Algorithm: - 1. Develop >= n bits of src.num / src.den, where n is the number of bits - in a double. This (partial) division will use all bits from the - denominator. - 2. Use the remainder to determine how to round the result. - 3. Assign the integral result to a temporary double. - 4. Scale the temporary double, and return the result. - - An alternative algorithm, that would be faster: - 0. Let n be somewhat larger than the number of significant bits in a double. - 1. Extract the most significant n bits of the denominator, and an equal - number of bits from the numerator. - 2. Interpret the extracted numbers as integers, call them a and b - respectively, and develop n bits of the fractions ((a + 1) / b) and - (a / (b + 1)) using mpn_divrem. - 3. If the computed values are identical UP TO THE POSITION WE CARE ABOUT, - we are done. If they are different, repeat the algorithm from step 1, - but first let n = n * 2. - 4. If we end up using all bits from the numerator and denominator, fall - back to the first algorithm above. - 5. Just to make life harder, The computation of a + 1 and b + 1 above - might give carry-out... Needs special handling. It might work to - subtract 1 in both cases instead. -*/ - void #if __STDC__ mpf_set_q (mpf_t r, mpq_srcptr q) @@ -132,13 +107,17 @@ mpf_set_q (r, q) } else { - nlimb = mpn_lshift (rp, np, nsize, normalization_steps); + nlimb = mpn_lshift (rp, np, rsize, normalization_steps); } if (nlimb != 0) { rp[rsize] = nlimb; - rsize++; exp++; + /* Don't just increase rsize, chop off rp at the low end instead. */ + if (rsize == prec) + rp++; + else + rsize++; } } else @@ -164,7 +143,7 @@ mpf_set_q (r, q) } EXP (r) = exp; - SIZ (r) = qsize; + SIZ (r) = sign_quotient >= 0 ? qsize : -qsize; TMP_FREE (marker); } |