xlitob.c 1.03 KB
/* _Litob function */
#include <stdlib.h>
#include <string.h>
#include "xmath.h"
#include "xstdio.h"

static char ldigs[] = "0123456789abcdef";
static char udigs[] = "0123456789ABCDEF";

void _Litob(_Pft *px, char code)
{	/* convert unsigned long to text */
	char ac[24];	/* safe for 64-bit integers */
	char *digs = code == 'X' ? udigs : ldigs;
	int base = code == 'o' ? 8 : code != 'x' && code != 'X' ? 10 : 16;
	int i = sizeof(ac);
	unsigned long long ullval = px->v.ll;

	if ((code == 'd' || code == 'i') && px->v.ll < 0)
		ullval = -ullval;	/* safe against overflow */
	if (ullval || px->prec)
		ac[--i] = digs[ullval % base];
	px->v.ll = ullval / base;
	while (0 < px->v.ll && 0 < i) {	/* convert digits */
		lldiv_t qr = lldiv(px->v.ll, (long long) base);

		px->v.ll = qr.quot;
		ac[--i] = digs[qr.rem];
	}
	px->n1 = sizeof(ac) - i;
	memcpy(px->s, &ac[i], px->n1);
	if (px->n1 < px->prec)
		px->nz0 = px->prec - px->n1;
	if (px->prec < 0 && (px->flags & (_FMI | _FZE)) == _FZE
		&& 0 < (i = px->width - px->n0 - px->nz0 - px->n1))
		px->nz0 += i;
}