1 /* mpf_get_str (digit_ptr, exp, base, n_digits, a) -- Convert the floating
2 point number A to a base BASE number and store N_DIGITS raw digits at
3 DIGIT_PTR, and the base BASE exponent in the word pointed to by EXP. For
4 example, the number 3.1416 would be returned as "31416" in DIGIT_PTR and
7 Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
9 This file is part of the GNU MP Library.
11 The GNU MP Library is free software; you can redistribute it and/or modify
12 it under the terms of the GNU Library General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or (at your
14 option) any later version.
16 The GNU MP Library is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
19 License for more details.
21 You should have received a copy of the GNU Library General Public License
22 along with the GNU MP Library; see the file COPYING.LIB. If not, write to
23 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
24 MA 02111-1307, USA. */
31 New algorithm for converting fractions (951019):
32 0. Call the fraction to convert F.
33 1. Compute [exp * log(2^BITS_PER_MP_LIMB)/log(B)], i.e.,
34 [exp * BITS_PER_MP_LIMB * __mp_bases[B].chars_per_bit_exactly]. Exp is
35 the number of limbs between the limb point and the most significant
36 non-zero limb. Call this result n.
38 3. F*B^n will now be just below 1, which can be converted easily. (Just
39 multiply by B repeatedly, and see the digits fall out as integers.)
40 We should interrupt the conversion process of F*B^n as soon as the number
41 of digits requested have been generated.
43 New algorithm for converting integers (951019):
44 0. Call the integer to convert I.
45 1. Compute [exp * log(2^BITS_PER_MP_LIMB)/log(B)], i.e.,
46 [exp BITS_PER_MP_LIMB * __mp_bases[B].chars_per_bit_exactly]. Exp is
47 the number of limbs between the limb point and the least significant
48 non-zero limb. Call this result n.
50 3. I/B^n can be converted easily. (Just divide by B repeatedly. In GMP,
51 this is best done by calling mpn_get_str.)
52 Note that converting I/B^n could yield more digits than requested. For
53 efficiency, the variable n above should be set larger in such cases, to
54 kill all undesired digits in the division in step 3.
59 mpf_get_str (char *digit_ptr, mp_exp_t *exp, int base, size_t n_digits, mpf_srcptr u)
61 mpf_get_str (digit_ptr, exp, base, n_digits, u)
74 long i; /* should be size_t */
77 size_t digits_computed_so_far;
92 num_to_text = "0123456789abcdefghijklmnopqrstuvwxyz";
97 num_to_text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
100 /* Don't compute more digits than U can accurately represent.
101 Also, if 0 digits were requested, give *exactly* as many digits
102 as can be accurately represented. */
104 size_t max_digits = (((u->_mp_prec - 1) * BITS_PER_MP_LIMB)
105 * __mp_bases[base].chars_per_bit_exactly);
106 if (n_digits == 0 || n_digits > max_digits)
107 n_digits = max_digits;
112 /* We didn't get a string from the user. Allocate one (and return
113 a pointer to it) with space for `-' and terminating null. */
114 digit_ptr = (char *) (*_mp_allocate_func) (n_digits + 2);
124 str = (unsigned char *) digit_ptr;
126 /* Allocate temporary digit space. We can't put digits directly in the user
127 area, since we almost always generate more digits than requested. */
128 tstr = (unsigned char *) TMP_ALLOC (n_digits + 3 * BITS_PER_MP_LIMB);
137 digits_computed_so_far = 0;
141 /* The number has just an integral part. */
143 mp_size_t exp_in_limbs;
151 n_limbs = 2 + ((mp_size_t) (n_digits / __mp_bases[base].chars_per_bit_exactly)
154 /* Compute n such that [u/B^n] contains (somewhat) more than n_digits
155 digits. (We compute less than that only if that is an exact number,
156 i.e., exp is small enough.) */
160 if (n_limbs >= exp_in_limbs)
162 /* The number is so small that we convert the entire number. */
164 rp = (mp_ptr) TMP_ALLOC (exp_in_limbs * BYTES_PER_MP_LIMB);
165 MPN_ZERO (rp, exp_in_limbs - usize);
166 MPN_COPY (rp + (exp_in_limbs - usize), u->_mp_d, usize);
167 rsize = exp_in_limbs;
171 exp_in_limbs -= n_limbs;
172 exp_in_base = (((exp_in_limbs * BITS_PER_MP_LIMB - 1))
173 * __mp_bases[base].chars_per_bit_exactly);
175 rsize = exp_in_limbs + 1;
176 rp = (mp_ptr) TMP_ALLOC (rsize * BYTES_PER_MP_LIMB);
177 tp = (mp_ptr) TMP_ALLOC (rsize * BYTES_PER_MP_LIMB);
182 count_leading_zeros (cnt, exp_in_base);
183 for (i = BITS_PER_MP_LIMB - cnt - 2; i >= 0; i--)
185 mpn_mul_n (tp, rp, rp, rsize);
187 rsize -= tp[rsize - 1] == 0;
188 xp = tp; tp = rp; rp = xp;
190 if (((exp_in_base >> i) & 1) != 0)
192 cy = mpn_mul_1 (rp, rp, rsize, (mp_limb_t) base);
207 mp_ptr tmp = (mp_ptr) TMP_ALLOC ((rsize+1)* BYTES_PER_MP_LIMB);
208 MPN_ZERO (tmp, rsize - msize);
209 MPN_COPY (tmp + rsize - msize, mp, msize);
215 mp_ptr tmp = (mp_ptr) TMP_ALLOC ((msize+1)* BYTES_PER_MP_LIMB);
216 MPN_COPY (tmp, mp, msize);
219 count_leading_zeros (cnt, rp[rsize - 1]);
223 mpn_lshift (rp, rp, rsize, cnt);
224 cy = mpn_lshift (mp, mp, msize, cnt);
230 mp_size_t qsize = n_limbs + (cy != 0);
231 qp = (mp_ptr) TMP_ALLOC ((qsize + 1) * BYTES_PER_MP_LIMB);
232 xtra = qsize - (msize - rsize);
233 qflag = mpn_divrem (qp, xtra, mp, msize, rp, rsize);
235 rsize = qsize + qflag;
241 str_size = mpn_get_str (tstr, base, rp, rsize);
243 if (str_size > n_digits + 3 * BITS_PER_MP_LIMB)
247 while (tstr[start_str] == 0)
250 for (i = start_str; i < str_size; i++)
252 tstr[digits_computed_so_far++] = tstr[i];
253 if (digits_computed_so_far > n_digits)
256 exp_in_base = exp_in_base + str_size - start_str;
264 /* The number has an integral part, convert that first.
265 If there is a fractional part too, it will be handled later. */
268 rp = (mp_ptr) TMP_ALLOC (uexp * BYTES_PER_MP_LIMB);
269 up = u->_mp_d + usize - uexp;
270 MPN_COPY (rp, up, uexp);
272 str_size = mpn_get_str (tstr, base, rp, uexp);
275 while (tstr[start_str] == 0)
278 for (i = start_str; i < str_size; i++)
280 tstr[digits_computed_so_far++] = tstr[i];
281 if (digits_computed_so_far > n_digits)
283 exp_in_base = str_size - start_str;
288 exp_in_base = str_size - start_str;
289 /* Modify somewhat and fall out to convert fraction... */
297 /* Convert the fraction. */
299 mp_size_t rsize, msize;
300 mp_ptr rp, tp, xp, mp;
305 big_base = __mp_bases[base].big_base;
306 dig_per_u = __mp_bases[base].chars_per_limb;
308 /* Hack for correctly (although not efficiently) converting to bases that
309 are powers of 2. If we deem it important, we could handle powers of 2
310 by shifting and masking (just like mpn_get_str). */
311 if (big_base < 10) /* logarithm of base when power of two */
313 int logbase = big_base;
314 if (dig_per_u * logbase == BITS_PER_MP_LIMB)
316 big_base = (mp_limb_t) 1 << (dig_per_u * logbase);
317 /* fall out to general code... */
323 rp = (mp_ptr) TMP_ALLOC (usize * BYTES_PER_MP_LIMB);
325 MPN_COPY (rp, up, usize);
333 if (u->_mp_d[usize - 1] == 0)
336 count_leading_zeros (cnt, u->_mp_d[usize - 1]);
338 nexp = ((uexp * BITS_PER_MP_LIMB) + cnt)
339 * __mp_bases[base].chars_per_bit_exactly;
343 rp = (mp_ptr) TMP_ALLOC (usize * BYTES_PER_MP_LIMB);
345 MPN_COPY (rp, up, usize);
351 rp = (mp_ptr) TMP_ALLOC (rsize * BYTES_PER_MP_LIMB);
352 tp = (mp_ptr) TMP_ALLOC (rsize * BYTES_PER_MP_LIMB);
357 count_leading_zeros (cnt, nexp);
358 for (i = BITS_PER_MP_LIMB - cnt - 2; i >= 0; i--)
360 mpn_mul_n (tp, rp, rp, rsize);
362 rsize -= tp[rsize - 1] == 0;
363 xp = tp; tp = rp; rp = xp;
365 if (((nexp >> i) & 1) != 0)
367 cy = mpn_mul_1 (rp, rp, rsize, (mp_limb_t) base);
373 /* Did our multiplier (base^nexp) cancel with uexp? */
379 cy = mpn_mul_1 (rp, rp, rsize, big_base);
389 tp = (mp_ptr) TMP_ALLOC ((rsize + msize) * BYTES_PER_MP_LIMB);
391 cy = mpn_mul (tp, rp, rsize, mp, msize);
393 cy = mpn_mul (tp, mp, msize, rp, rsize);
398 /* If we already output digits (for an integral part) pad
400 if (digits_computed_so_far != 0)
401 for (i = 0; i < nexp; i++)
402 tstr[digits_computed_so_far++] = 0;
405 while (digits_computed_so_far <= n_digits)
407 /* For speed: skip trailing zeroes. */
414 n_digits = digits_computed_so_far;
419 cy = mpn_mul_1 (rp, rp, rsize, big_base);
420 if (digits_computed_so_far == 0 && cy == 0)
426 /* Convert N1 from BIG_BASE to a string of digits in BASE
427 using single precision operations. */
429 unsigned char *s = tstr + digits_computed_so_far + dig_per_u;
430 for (i = dig_per_u - 1; i >= 0; i--)
436 digits_computed_so_far += dig_per_u;
438 if (exp_in_base == 0)
444 /* We can have at most one leading 0. Remove it. */
448 digits_computed_so_far--;
452 /* We should normally have computed too many digits. Round the result
453 at the point indicated by n_digits. */
454 if (digits_computed_so_far > n_digits)
456 /* Round the result. */
457 if (tstr[n_digits] * 2 >= base)
459 digits_computed_so_far = n_digits;
460 for (i = n_digits - 1; i >= 0; i--)
466 digits_computed_so_far--;
469 digits_computed_so_far = 1;
475 /* We might have fewer digits than requested as a result of rounding above,
476 (i.e. 0.999999 => 1.0) or because we have a number that simply doesn't
477 need many digits in this base (i.e., 0.125 in base 10). */
478 if (n_digits > digits_computed_so_far)
479 n_digits = digits_computed_so_far;
481 /* Remove trailing 0. There can be many zeros. */
482 while (n_digits != 0 && tstr[n_digits - 1] == 0)
485 /* Translate to ascii and null-terminate. */
486 for (i = 0; i < n_digits; i++)
487 *str++ = num_to_text[tstr[i]];
494 #if COPY_THIS_TO_OTHER_PLACES
495 /* Use this expression in lots of places in the library instead of the
496 count_leading_zeros+expression that is used currently. This expression
497 is much more accurate and will save odles of memory. */
498 rsize = ((mp_size_t) (exp_in_base / __mp_bases[base].chars_per_bit_exactly)
499 + BITS_PER_MP_LIMB) / BITS_PER_MP_LIMB;