#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