char *ftoa( FLOATVAL *flt ) { #ifdef __WATCOMC__ CVT_INFO cvt; char mant[MAX_DIGIT + 1]; cvt.flags = G_FMT + F_CVT + NO_TRUNC + LONG_DOUBLE; cvt.scale = 1; cvt.ndigits = MAX_DIGIT; cvt.expwidth = 0; cvt.expchar = 0; __LDcvt( &flt->ld, &cvt, mant ); if( !isdigit( *mant ) ) { /* special magical thingy (nan, inf, ...) */ strcpy( buf, mant ); return( buf ); } if( *mant != '0' ) --cvt.decimal_place; sprintf( buf, "%c%c.%sE%+1d", ( cvt.sign ) ? '-' : '+', *mant, mant + 1, cvt.decimal_place ); #else #ifdef _LONG_DOUBLE_ double dbl; long_double ld; ld = flt->ld; __iLDFD( &ld, &dbl ); sprintf( buf, "%.19e", dbl ); #else sprintf( buf, "%.19e", flt->ld ); #endif #endif return( buf ); }
char *__cvt( double value, int ndigits, int *dec, int *sign, int fmt, char *buf ) { CVT_INFO cvt; long_double ld; #ifdef _LONG_DOUBLE_ double double_value; /* convert this double into a long double */ double_value = value; __iFDLD( &double_value, &ld ); #else ld.value = value; #endif if( fmt == 'F' ) { // fcvt passes in 'F' cvt.flags = F_FMT + F_CVT; cvt.scale = 0; } else { // ecvt passes in 'G' cvt.flags = G_FMT + F_CVT; cvt.scale = 1; } cvt.ndigits = ndigits; cvt.expwidth = 0; cvt.expchar = fmt; __LDcvt( &ld, &cvt, buf ); *dec = cvt.decimal_place; *sign = cvt.sign; return( buf ); }
/* Dump a long_double value */ void DumpALD( long_double *pld ) { CVT_INFO cvt; char buf[256]; cvt.ndigits = 20; cvt.scale = 0; cvt.flags = G_FMT | NO_TRUNC; cvt.expchar = 'e'; cvt.expwidth = 8; __LDcvt( pld, &cvt, buf ); printf( "%s", buf ); }
FLTSUPPFUNC FAR_STRING _EFG_Format( char *buffer, my_va_list *args, _mbcs_SPECS __SLIB *specs ) { int digits; int fmt; CVT_INFO cvt; double double_value; long_double ld; cvt.expchar = specs->_character; /* 'e', 'g' exponent character */ digits = specs->_prec; fmt = specs->_character & 0x5F; if( fmt == 'G' ) { if( digits == 0 ) digits = 1; /* 27-oct-88 */ cvt.expchar -= 2; /* change exponent to 'e' or 'E' */ cvt.flags = G_FMT; cvt.scale = 1; } else if( fmt == 'E' ) { cvt.flags = E_FMT; cvt.scale = 1; } else { cvt.flags = F_FMT; cvt.scale = 0; } if( !(specs->_character & 0x20) ) { /* test for 'E', 'F', or 'G' */ cvt.flags |= IN_CAPS; /* INF/NAN needs to be uppercase */ } if( specs->_flags & SPF_ALT ) { cvt.flags |= F_DOT; } if( (specs->_flags & SPF_LONG_DOUBLE) && !_LDisDouble() ) { ld = va_arg( args->v, long_double ); cvt.flags |= LONG_DOUBLE; } else { double_value = va_arg( args->v, double ); #ifdef _LONG_DOUBLE_ /* convert this double into a long double */ __iFDLD( &double_value, &ld ); #else ld.u.value = double_value; #endif } if( digits == -1 ) { digits = 6; } cvt.ndigits = digits; cvt.expwidth = 2; // Only relevant for E format __LDcvt( &ld, &cvt, buffer + 1 ); specs->_n1 = cvt.n1; specs->_nz1 = cvt.nz1; specs->_n2 = cvt.n2; specs->_nz2 = cvt.nz2; if( cvt.flags & IS_INF_NAN ) { specs->_pad_char = ' '; /* No zero padding for inf/nan! */ } if( cvt.sign < 0 ) { buffer[specs->_n0++] = '-'; } else if( specs->_flags & SPF_FORCE_SIGN ) { buffer[specs->_n0++] = '+'; } else if( specs->_flags & SPF_BLANK ) { buffer[specs->_n0++] = ' '; } return( buffer ); } /* _EFG_Format() */