#include <config.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdarg.h>
#include "bcmath.h"
#include "private.h"
typedef struct stk_rec {
long digit;
struct stk_rec *next;
} stk_rec;
static char ref_str[] = "0123456789ABCDEF";
void
bc_out_long (val, size, space, out_char)
long val;
int size, space;
#ifdef __STDC__
void (*out_char)(int);
#else
void (*out_char)();
#endif
{
char digits[40];
int len, ix;
if (space) (*out_char) (' ');
snprintf(digits, sizeof(digits), "%ld", val);
len = strlen (digits);
while (size > len)
{
(*out_char) ('0');
size--;
}
for (ix=0; ix < len; ix++)
(*out_char) (digits[ix]);
}
void
#ifdef __STDC__
bc_out_num (bc_num num, int o_base, void (*out_char)(int), int leading_zero TSRMLS_DC)
#else
bc_out_num (bc_num num, int o_base, void (*out_char)(), int leading_zero TSRMLS_DC)
#endif
{
char *nptr;
int index, fdigit, pre_space;
stk_rec *digits, *temp;
bc_num int_part, frac_part, base, cur_dig, t_num, max_o_digit;
if (num->n_sign == MINUS) (*out_char) ('-');
if (bc_is_zero (num TSRMLS_CC))
(*out_char) ('0');
else
if (o_base == 10)
{
nptr = num->n_value;
if (num->n_len > 1 || *nptr != 0)
for (index=num->n_len; index>0; index--)
(*out_char) (BCD_CHAR(*nptr++));
else
nptr++;
if (leading_zero && bc_is_zero (num TSRMLS_CC))
(*out_char) ('0');
if (num->n_scale > 0)
{
(*out_char) ('.');
for (index=0; index<num->n_scale; index++)
(*out_char) (BCD_CHAR(*nptr++));
}
}
else
{
if (leading_zero && bc_is_zero (num TSRMLS_CC))
(*out_char) ('0');
digits = NULL;
bc_init_num (&int_part TSRMLS_CC);
bc_divide (num, BCG(_one_), &int_part, 0 TSRMLS_CC);
bc_init_num (&frac_part TSRMLS_CC);
bc_init_num (&cur_dig TSRMLS_CC);
bc_init_num (&base TSRMLS_CC);
bc_sub (num, int_part, &frac_part, 0);
int_part->n_sign = PLUS;
frac_part->n_sign = PLUS;
bc_int2num (&base, o_base);
bc_init_num (&max_o_digit TSRMLS_CC);
bc_int2num (&max_o_digit, o_base-1);
while (!bc_is_zero (int_part TSRMLS_CC))
{
bc_modulo (int_part, base, &cur_dig, 0 TSRMLS_CC);
temp = (stk_rec *) emalloc (sizeof(stk_rec));
if (temp == NULL) bc_out_of_memory();
temp->digit = bc_num2long (cur_dig);
temp->next = digits;
digits = temp;
bc_divide (int_part, base, &int_part, 0 TSRMLS_CC);
}
if (digits != NULL)
{
while (digits != NULL)
{
temp = digits;
digits = digits->next;
if (o_base <= 16)
(*out_char) (ref_str[ (int) temp->digit]);
else
bc_out_long (temp->digit, max_o_digit->n_len, 1, out_char);
efree (temp);
}
}
if (num->n_scale > 0)
{
(*out_char) ('.');
pre_space = 0;
t_num = bc_copy_num (BCG(_one_));
while (t_num->n_len <= num->n_scale) {
bc_multiply (frac_part, base, &frac_part, num->n_scale TSRMLS_CC);
fdigit = bc_num2long (frac_part);
bc_int2num (&int_part, fdigit);
bc_sub (frac_part, int_part, &frac_part, 0);
if (o_base <= 16)
(*out_char) (ref_str[fdigit]);
else {
bc_out_long (fdigit, max_o_digit->n_len, pre_space, out_char);
pre_space = 1;
}
bc_multiply (t_num, base, &t_num, 0 TSRMLS_CC);
}
bc_free_num (&t_num);
}
bc_free_num (&int_part);
bc_free_num (&frac_part);
bc_free_num (&base);
bc_free_num (&cur_dig);
bc_free_num (&max_o_digit);
}
}