/*ident "@(#)cls4:lib/stream/flt.c 1.2.1.7" */ /******************************************************************************* C++ source for the C++ Language System, Release 3.0. This product is a new release of the original cfront developed in the computer science research center of AT&T Bell Laboratories. Copyright (c) 1993 UNIX System Laboratories, Inc. Copyright (c) 1991, 1992 AT&T and UNIX System Laboratories, Inc. Copyright (c) 1984, 1989, 1990 AT&T. All Rights Reserved. THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE of AT&T and UNIX System Laboratories, Inc. The copyright notice above does not evidence any actual or intended publication of such source code. *******************************************************************************/ #include #include #include #include #include #include // for frexp() #define OSTREAM ostream #define ISTREAM istream // This file contains all the functions having to do with i/o of // floats and doubles. It drags in lots of stuff from stdio, which // is why I made it separate. istream& ISTREAM::operator>>(double& d) /* {+|-} d* {.} d* { e|E {+|-} d+ } except that - a dot must be pre- or succeeded by at least one digit - an exponent must be preceded by at least one digit */ { register int c = 0; register int anydigits = 0 ; char buf[256]; register char* p = buf; register streambuf* nbp = bp; if (!ipfx() ) return *this ; /* get the sign */ switch (c = nbp->sgetc()) { case EOF: setstate(eofbit|failbit) ; return *this; case '-': case '+': *p++ = c; c = bp->snextc(); } /* get integral part */ while (isdigit(c)) { *p++ = c; c = bp->snextc(); anydigits = 1 ; } /* get fraction */ if (c == '.') { do { *p++ = c; c = bp->snextc(); anydigits = 1 ; } while (isdigit(c)); } /* get exponent */ if ( anydigits && (c == 'e' || c == 'E')) { *p++ = c; switch (c = nbp->snextc()) { case EOF: setstate(eofbit|failbit) ; return *this; case '-': case '+': *p++ = c; c = bp->snextc(); } while (isdigit(c)) { *p++ = c; c = bp->snextc(); } } *p = 0; d = atof(buf); if (c == EOF) setstate(eofbit) ; if (!anydigits) setstate(badbit) ; return *this; } istream& ISTREAM::operator>>(float& f) { double d; if (!ipfx() ) return *this ; *this >> d ; if ( good() || rdstate() == eofbit ) f = d; return *this; } ostream& OSTREAM::operator<<(float f) { return *this << (double)f ; } //static const int fltbits = ios::scientific|ios::fixed|ios::uppercase ; ostream& OSTREAM::operator<<(double d) { char buf[256]; int w = width(0) ; int p = precision() ; int explicitp = ( p > 0 ) || (flags()&ios::fixed) ; if (!opfx()) return *this; // long bits = flags() & fltbits ; char fmt[256] ; strcpy(fmt,"%") ; if ( flags() & ios::showpoint ) { strcat(fmt,"#") ; } if ( flags() & ios::showpos ) { strcat(fmt,"+") ; } if ( explicitp ) { strcat(fmt,".*") ; } long mode = flags() & (ios::scientific|ios::fixed|ios::uppercase); switch(mode) { case ios::scientific : strcat(fmt,"e") ; break ; case ios::scientific|ios::uppercase : strcat(fmt,"E") ; break; case ios::fixed : strcat(fmt,"f") ; break ; case ios::fixed|ios::uppercase: strcat(fmt,"f") ; break ; case ios::uppercase : strcat(fmt,"G") ; break ; default : strcat(fmt,"g") ; break ; } char *result; char *localbuf = 0; result = buf; if ( explicitp ) { if (flags()&ios::fixed) { int exponent; /*double jnk =*/ frexp(d, &exponent); localbuf = new char[p+(exponent>0 ? 4+exponent/3 : 4)]; // need 3 extra cells, one for sign, // one for decimal point, one for null sprintf(localbuf,fmt,p,d) ; result = localbuf; } else if (p < 25) { sprintf(buf,fmt,p,d) ; } else { localbuf = new char[p + 10]; sprintf(localbuf,fmt,p,d) ; result = localbuf; } } else { sprintf(buf,fmt,d) ; } int padf = w-strlen(result) ; if ( padf < 0 ) padf = 0 ; if ( padf && !(flags()&ios::left) ) { if (flags()&ios::internal) if (*result == '+' || *result == '-') put(*result++); while ( padf-- > 0 ) put(fill()) ; } *this << result ; while ( padf-- > 0 ) put(fill()) ; osfx() ; if (localbuf != 0) delete localbuf; return *this ; }