blob: d5b04c182c5bdc179625670838fd2a303ab9a8a6 [file] [log] [blame]
#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;
}