Files
Digital-Research-Source-Code/CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/clib/doprtfp.c
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

182 lines
6.7 KiB
C

/***************************************************************************
*
* d o p r t f p R o u t i n e
* -----------------------------
*
* This file contains subroutines called from "_doprt()" which are
* specific to floating point. The purpose of having a separate file
* is so that these routines may be declared global in a special
* version of "s.o", to allow running without the floating point
* library routines.
*
* Entry Points:
*
* _petoa(^float, ^buff, prec);
* _pftoa(^float, ^buff, prec);
* _pgtoa(^float, ^buff, prec);
*
* ^float is a pointer to the floating number to convert
* ^buff is a pointer to the buffer
* prec is the precision specifier
*
* Modifications:
* 1/84 whf - change to include "osif.h"
* 8/83 whf - add in DRC floating point call
* 10/83 whf - get it to work on DRC
*
*****************************************************************************/
/* */
#include "portab.h" /* */
#include "osif.h" /* */
/* */
/****************************************************************************/
#if CPM68K /* I hope to resolve these differences someday. whf 8/83 */
/****************************************************************************/
BYTE *ftoa(); /* Converts float to ascii "F" fmt */
BYTE *etoa(); /* Converts float to ascii "E" fmt */
/************************************/
BYTE *_pftoa(addr,buf,prec) /* Print "F" format */
FLOAT *addr; /* -> Number to convert */
BYTE *buf; /* -> Output buffer */
WORD prec; /* Fraction precision specifier */
{ /************************************/
FLOAT fp; /* Float temp */
/************************************/
prec = (prec < 0) ? 6 : prec; /* If < 0, make it 6 */
fp = *addr; /* Load float number */
return(ftoa(fp,buf,prec)); /* Do conversion */
} /************************************/
/* */
BYTE *_petoa(addr,buf,prec) /* Print "E" format */
FLOAT *addr; /* -> Number to convert */
BYTE *buf; /* -> Output buffer */
WORD prec; /* Fraction precision specifier */
{ /************************************/
FLOAT fp; /* Floating temp */
prec = (prec < 0) ? 6 : prec; /* If < 0, make it 6 */
fp = *addr; /* Load temp */
return(etoa(fp,buf,prec)); /* Do conversion */
} /************************************/
/* */
BYTE *_pgtoa(addr,buf,prec) /* Print "G" format */
FLOAT *addr; /* -> Number to convert */
BYTE *buf; /* -> Output buffer */
WORD prec; /* Fraction precision specifier */
{ /************************************/
BYTE *sp; /* String temp */
/************************************/
sp = _pftoa(addr, buf, prec); /* Try F first */
if(strlen(buf) > (7+prec)) /* Smallest FP string */
sp = _petoa(addr,buf,prec); /* Do E format instead */
return sp; /* */
} /************************************/
/* */
/****************************************************************************/
#else /* for DRC */
/****************************************************************************/
/* */
BYTE *ftoa(); /* General purpose floating point */
/* */
BYTE *_drcftoa(addr,buf,prec,kind) /* Use DRC ftoa routine */
DOUBLE *addr; /* -> Number to convert */
REG BYTE *buf; /* -> Output buffer */
REG WORD prec; /* Fraction precision specifier */
BYTE kind; /* Kind of convert (f, e, or g) */
{ /************************************/
REG BYTE *ss; /* Temp pointer for adjustment */
REG WORD nn; /* Counter */
WORD len; /* */
/* */
ss = buf; /* Save til later */
if( prec < 0) prec = 6; /* If <0, make it 6 */
if( prec > 17 ) prec = 17; /* If >17, make it 17 */
if( kind == 'f' ) nn = 17; /* use max. precision */
else if( kind == 'e' || kind == 'E' )
nn = prec + 1;
else if( (nn = prec) == 0 ) /* G format */
++nn;
if (nn > 17) nn = 17;
*buf = ' ';
ftoa(addr, &buf[1], 80, nn, kind); /* go convert */
if( kind == 'f' )
_ffmt(ss,prec);
len = strlen(buf);
if(buf[len-1] == '.') /* Zap trailing decimal point */
buf[len-1] = NULL; /* */
while( *buf == ' ' ) /* Zap leading blanks */
++buf; /* */
if( ss != buf ) /* Did we zap leading blanks? */
strcpy(ss,buf); /* Ifso, shift everything into place*/
return ss; /* */
} /************************************/
BYTE *_pftoa(addr,buf,prec,ch) /* Print "F" format */
FLOAT *addr; /* -> Number to convert */
BYTE *buf; /* -> Output buffer */
WORD prec; /* Fraction precision specifier */
BYTE ch; /* Char format specifier */
{ /************************************/
return(_drcftoa(addr,buf,prec,ch));/* Do conversion */
} /************************************/
/* */
BYTE *_petoa(addr,buf,prec,ch) /* Print "E" format */
FLOAT *addr; /* -> Number to convert */
BYTE *buf; /* -> Output buffer */
WORD prec; /* Fraction precision specifier */
BYTE ch; /* Char format specifier */
{ /************************************/
return(_drcftoa(addr,buf,prec,ch));/* Do conversion */
} /************************************/
/* */
BYTE *_pgtoa(addr,buf,prec,ch) /* Print "G" format */
FLOAT *addr; /* -> Number to convert */
BYTE *buf; /* -> Output buffer */
WORD prec; /* Fraction precision specifier */
BYTE ch; /* Char format specifier */
{ /************************************/
return(_drcftoa(addr,buf,prec,ch));/* Do conversion */
} /************************************/
/****************************************************************************/
MLOCAL _ffmt(s, prec)
char *s;
register prec;
{
register char *p;
register int i;
char *dot, lastdig;
p = s;
while (*++p) {
if (*p == '.') dot = p; /* found decimal pt. */
else if (*p == 'e') {
s = dot + prec + 1;
if (s < p)
while (*s++ = *p++); /* remove extra zeros */
return;
}
}
i = p - dot - 1;
while (i++ < prec)
*p++ = '0'; /* fill trailing zeros */
p = dot + prec + 1;
lastdig = *p;
*p = '\0';
if (lastdig >= '5') {
while (1) { /* round preceeding digit */
if (*--p == '.') p--;
if ((*p += 1) <= '9') break;
*p = '0';
}
if (*p < '1') {
if (*p == '.') *(p-1) = '-';
*p = '1';
}
}
}
#endif
/****************************************************************************/