#include "fp_support.h"

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>

char * DtoER (double v) {

	static char buf[200];
	
	sprintf(buf, "%0.14E", v);
	return parse_ereal(buf);
}

char * DtoR (double v) {

	static char buf[200];
	
	sprintf(buf, "%0.11E", v);
	return parse_real(buf);
}

static char * chrtostr (int c) {

	static char buf[2];

	buf[0] = c;
	buf[1] = (char)0;
	
	return buf;
} 

static char * strrev (char * s) {

	static char buf[200];
	int l;
	char * d;
	
	l = strlen(s);
	
	d = buf + l;
	
	*d = (char)0;
	d--;
	
	while (l) {
		
		*d = *s;
		d--;
		s++;
	
		l--;
	}

	return buf;
}

/* The following code is (C) by Alex Ramos, <ramos@engr.LaTech.edu> */
/* ANSI-fied by Lutz Vieweg <lkv@mania.robin.de> 1994 */

#ifndef NULL
#define NULL 0
#endif

#ifndef TRUE
#define TRUE -1
#endif

#ifndef FALSE
#define FALSE 0
#endif

char * parse_ereal(char * s)
/*
 * Example input: 3.14E-10 Example output: 099990000000000004130
 */
{
    char           *c;
    c = parse_float(s, 15, 5);      /* HP48's extended real */
    if (c != NULL)
        return c;
    /* error("Extended-real number expected.\n"); */
    return NULL;
}


char *parse_real(char * s)
{
    char           *c;
    c = parse_float(s, 12, 3);      /* HP48's single-precision real */
    if (c != NULL)
        return c;
    /* error("Real number expected.\n"); */
    return NULL;
}


char *parse_float(char * s, int size_mantissa, int size_exponent)
/* Returns NULL on invalid syntax */
/* Designed for the HP48 -> All half-bytes are reversed in the output */

/* (C) Alex Ramos 1993 */

#define INVALID_EXP (-7)        /* Any invalid  implicit exponent */

{
    char            mant[100];      /* char mant[size_mantissa + 1]; is
                                     * illegal */
    long            exp_exp = 0;    /* explicit exponent */
    int             imp_exp = INVALID_EXP,  /* implicit exponent (due to
                                             * decimal period) */
            sign = 1,       /* overall sign */
            exp_sign = 1,   /* exponent sign */
            lz_exp = 0,     /* Exponent implicited by leading
                     * zeroes */
            ptr;    /* linear parsing pointer */
    int             exparse = FALSE, nonzero = FALSE;
    *mant = '\0';

    ptr = -1;
    while (s[++ptr]) {
        switch (s[ptr]) {
        case 'E':
        case 'e':
            if (exparse)
                return NULL;
            exparse = TRUE;
            if (imp_exp == INVALID_EXP)
                imp_exp = ptr - 1;
            break;
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            nonzero = TRUE; /* notice no break here */
        case '0':
            if (exparse)
                exp_exp = exp_exp * 10 + atoi(chrtostr(s[ptr]));

            else if (s[ptr] != '0' || nonzero) {
                if (strlen(mant) < size_mantissa)
                    strcat(mant, chrtostr(s[ptr]));
                else
                    return NULL;
            } else
                --lz_exp;

            break;

        case '-':
            if (exparse)
                exp_sign = -1;
            else {
                sign *= -1;
                ++s;
                --ptr;
            }

            break;
            
			case '+':
                ++s;
                --ptr;
            break;


        case '.':
            imp_exp = ptr - 1;
            break;

        default:
            return NULL;
        }
    }

    if (imp_exp == INVALID_EXP)
        imp_exp = ptr - 1;


    {

        static char out[100];
        char        fmt[20];
        int             i;
        long int        e = imp_exp + exp_sign * exp_exp + lz_exp;
        sprintf(fmt, "%c0%dld", '%', size_exponent);    /* e.g. "%05ld" */
        sprintf(out, fmt, e >= 0 ? e : ((long)pow(10.0, (double)size_exponent)) + e);
        strcpy(out, strrev(out));

        for (i = size_mantissa - 1; i >= 0; --i)
            strcat(out, chrtostr(i >= strlen(mant) ? '0' : mant[i]));
        strcat(out, chrtostr(sign == 1 ? '0' : '9'));

        return out; /* dupmark(out); */
    }

}




syntax highlighted by Code2HTML, v. 0.9.1