| #include "pdefs.h" |
| #include "precision.h" |
| |
| /* |
| * Convert a precision to a given base (the sign is ignored) |
| * |
| * Input: |
| * u - the number to convert |
| * dest - Where to put the ASCII representation radix |
| * WARNING! Not '\0' terminated, this is an exact image |
| * size - the number of digits of dest. |
| * (alphabet[0] padded on left) |
| * if size is too small, truncation occurs on left |
| * alphabet - A mapping from each radix digit to it's character digit |
| * (note: '\0' is perfectly OK as a digit) |
| * radix - The size of the alphabet, and the conversion radix |
| * 2 <= radix < 256. |
| * |
| * Returns: |
| * -1 if invalid radix |
| * 0 if successful |
| * >0 the number didn't fit |
| */ |
| int ptob(u, dest, size, alphabet, radix) |
| precision u; /* the number to convert */ |
| char *dest; /* where to place the converted ascii */ |
| unsigned int size; /* the size of the result in characters */ |
| char *alphabet; /* the character set forming the radix */ |
| register unsigned int radix; /* the size of the character set */ |
| { |
| register accumulator temp; |
| register unsigned int i; |
| register char *chp; |
| unsigned int lgclump; |
| int res = 0; |
| |
| precision r = pUndef, v = pUndef, pbase = pUndef; |
| |
| if (radix > 256 || radix < 2) return -1; |
| if (size == 0) return 1; |
| |
| (void) pparm(u); |
| temp = radix; |
| i = 1; |
| while (temp * radix > temp) { |
| temp *= radix; |
| i++; |
| } |
| lgclump = i; |
| |
| pset(&v, pabs(u)); |
| pset(&pbase, utop(temp)); /* assumes accumulator and int are the same! */ |
| |
| chp = dest + size; |
| do { |
| pdivmod(v, pbase, &v, &r); |
| temp = ptou(r); /* assumes accumulator and int are the same! */ |
| i = lgclump; |
| do { |
| *--chp = alphabet[temp % radix]; /* remainder */ |
| temp = temp / radix; |
| if (chp == dest) goto bail; |
| } while (--i > 0); |
| } while pnez(v); |
| |
| if (chp > dest) do { |
| *--chp = *alphabet; |
| } while (chp > dest); |
| |
| bail: |
| if (pnez(v) || temp != 0) { /* check for overflow */ |
| res = 1; |
| } |
| |
| pdestroy(pbase); |
| pdestroy(v); |
| pdestroy(r); |
| |
| pdestroy(u); |
| return res; |
| } |