home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1994 #1
/
monster.zip
/
monster
/
OS2
/
EMXFIX04.ZIP
/
CVT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-01-24
|
3KB
|
129 lines
/* cvt.c (emx+gcc) -- Copyright (c) 1994 by Eberhard Mattes */
#include <sys/emx.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <float.h>
/* Convert a non-zero floating point number to a string of decimal
digits and an exponent. The position of the decimal point is
assumed to be after the first digit. Examples:
1234567890123456789 --> 1234567890123456789, xp = 18
123 --> 1230000000000000000, xp = 2
12 --> 1200000000000000000, xp = 1
1.2 --> 1200000000000000000, xp = 0
0.12 --> 1200000000000000000, xp = -1
This function assumes that
LDBL_MANT_DIG <= 8 * sizeof (unsigned long long)
which is true for the extended real format (64-bit mantissa).
There are algothms which are more precise, but they're MUCH more
complicated. */
int _cvt_float_decimal (DOUBLE x, char *dst)
{
DOUBLE scaled;
unsigned long long intg;
int xp, len;
xp = (int)FLOOR (LOG10 (x));
scaled = x * POW (10.0, DIG - 1 - xp);
intg = (unsigned long long)scaled;
_ulltoa (intg, dst, 10);
len = strlen (dst);
if (len > DIG + 1)
abort ();
else if (len == DIG + 1)
{
++xp;
dst[DIG] = 0;
}
else if (len < DIG)
{
xp -= DIG - len;
memset (dst + len, '0', DIG - len);
dst[DIG] = 0;
}
return (xp);
}
/* Round a string of digits for truncating after PREC digits. Adjust
the exponent (pointed to by PXP) if required (for instance when
rounding "9999" to "1000"). */
void _cvt_round (char *dst, int *pxp, int prec, int lim)
{
/* Reduce the number of digits to the number of significant digits.
This is used to print zeros instead of `random' digits when
converting `double' floats with `long double' precision. */
if (prec > lim)
prec = lim; /* LIM is always <= DIG */
if (prec < 1)
prec = 1;
if (dst[prec] >= '5')
{
int i = prec;
while (i != 0 && dst[i-1] == '9')
{
dst[i-1] = '0';
--i;
}
if (i != 0)
++dst[i-1];
else
{
memmove (dst + 1, dst, DIG - 1);
dst[0] = '1';
++*pxp;
}
}
memset (dst + prec, '0', DIG - prec);
}
/* Remove trailing zeros from DIGITS for the "%g" format. Keep at
least KEEP digits at the start of DIGITS. */
void _cvt_remove_zeros (char *digits, int keep)
{
int i;
i = strlen (digits) - 1;
while (i >= keep && digits[i] == '0')
--i;
digits[i+1] = 0;
}
const char *_cvt_nan (int xam)
{
switch (xam)
{
case FX_P_NAN:
case FX_N_NAN:
return ("#NAN");
case FX_P_INFINITY:
return ("#INF");
case FX_N_INFINITY:
return ("-#INF");
case FX_P_EMPTY:
return ("#EMP");
case FX_N_EMPTY:
return ("-#EMP");
default:
return (NULL);
}
}