📄 num_put_float.cpp
字号:
#endif // !USE_SPRINTF_INSTEAD
#if !defined (USE_SPRINTF_INSTEAD)
// Reentrant versions of floating-point conversion functions. The argument
// lists look slightly different on different operating systems, so we're
// encapsulating the differences here.
# if defined (__CYGWIN__) || defined(__DJGPP)
static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf)
{ return ecvtbuf(x, n, pt, sign, buf); }
static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf)
{ return fcvtbuf(x, n, pt, sign, buf); }
# if !defined (_STLP_NO_LONG_DOUBLE)
static inline char* _Stl_qecvtR(long double x, int n, int* pt, int* sign, char* buf)
{ return ecvtbuf(x, n, pt, sign, buf); }
static inline char* _Stl_qfcvtR(long double x, int n, int* pt, int* sign, char* buf)
{ return fcvtbuf(x, n, pt, sign, buf); }
# endif
# elif defined (_STLP_USE_GLIBC)
static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf)
{ return buf + ecvt_r(x, n, pt, sign, buf, NDIG+2); }
static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf)
{ return buf + fcvt_r(x, n, pt, sign, buf, NDIG+2); }
# if !defined (_STLP_NO_LONG_DOUBLE)
static inline char* _Stl_qecvtR(long double x, int n, int* pt, int* sign, char* buf)
{ return buf + qecvt_r(x, n, pt, sign, buf, NDIG+2); }
static inline char* _Stl_qfcvtR(long double x, int n, int* pt, int* sign, char* buf)
{ return buf + qfcvt_r(x, n, pt, sign, buf, NDIG+2); }
# endif
# elif defined (_STLP_SCO_OPENSERVER) || defined (__NCR_SVR)
static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf)
{ return ecvt(x, n, pt, sign); }
static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf)
{ return fcvt(x, n, pt, sign); }
# if !defined (_STLP_NO_LONG_DOUBLE)
static inline char* _Stl_qecvtR(long double x, int n, int* pt, int* sign, char* buf)
{ return ecvtl(x, n, pt, sign); }
static inline char* _Stl_qfcvtR(long double x, int n, int* pt, int* sign, char* buf)
{ return fcvtl(x, n, pt, sign); }
# endif
# elif defined (__sun)
static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf)
{ return econvert(x, n, pt, sign, buf); }
static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf)
{ return fconvert(x, n, pt, sign, buf); }
# if !defined (_STLP_NO_LONG_DOUBLE)
static inline char* _Stl_qecvtR(long double x, int n, int* pt, int* sign, char* buf)
{ return qeconvert(&x, n, pt, sign, buf); }
static inline char* _Stl_qfcvtR(long double x, int n, int* pt, int* sign, char* buf)
{ return qfconvert(&x, n, pt, sign, buf); }
# endif
# elif defined (__DECCXX)
static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf)
{ return (ecvt_r(x, n, pt, sign, buf, NDIG)==0 ? buf : 0); }
static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf)
{ return (fcvt_r(x, n, pt, sign, buf, NDIG)==0 ? buf : 0); }
# if !defined (_STLP_NO_LONG_DOUBLE)
// fbp : no "long double" conversions !
static inline char* _Stl_qecvtR(long double x, int n, int* pt, int* sign, char* buf)
{ return (ecvt_r((double)x, n, pt, sign, buf, NDIG)==0 ? buf : 0) ; }
static inline char* _Stl_qfcvtR(long double x, int n, int* pt, int* sign, char* buf)
{ return (fcvt_r((double)x, n, pt, sign, buf, NDIG)==0 ? buf : 0); }
# endif
# elif defined (__hpux)
static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf)
{ return ecvt(x, n, pt, sign); }
static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf)
{ return fcvt(x, n, pt, sign); }
# if !defined (_STLP_NO_LONG_DOUBLE)
# if defined( _REENTRANT ) && (defined(_PTHREADS_DRAFT4) || defined(PTHREAD_THREADS_MAX))
static inline char* _Stl_qecvtR(long double x, int n, int* pt, int* sign, char* buf)
{ return (_ldecvt_r(*(long_double*)&x, n, pt, sign, buf, NDIG+2)==0 ? buf : 0); }
static inline char* _Stl_qfcvtR(long double x, int n, int* pt, int* sign, char* buf)
{ return (_ldfcvt_r(*(long_double*)&x, n, pt, sign, buf, NDIG+2)==0 ? buf : 0); }
# else
static inline char* _Stl_qecvtR(long double x, int n, int* pt, int* sign, char* buf)
{ return _ldecvt(*(long_double*)&x, n, pt, sign); }
static inline char* _Stl_qfcvtR(long double x, int n, int* pt, int* sign, char* buf)
{ return _ldfcvt(*(long_double*)&x, n, pt, sign); }
# endif
# endif
# elif defined (_AIX) || defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__)
static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf)
{ LOCK_CVT RETURN_CVT(ecvt, x, n, pt, sign, buf) }
static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf)
{ LOCK_CVT RETURN_CVT(fcvt, x, n, pt, sign, buf) }
# if !defined (_STLP_NO_LONG_DOUBLE)
static inline char* _Stl_qecvtR(long double x, int n, int* pt, int* sign, char* buf)
{ LOCK_CVT RETURN_CVT(ecvt, x, n, pt, sign, buf) }
static inline char* _Stl_qfcvtR(long double x, int n, int* pt, int* sign, char* buf)
{ LOCK_CVT RETURN_CVT(fcvt, x, n, pt, sign, buf) }
# endif
# elif defined (__unix) && !defined (__APPLE__) && !defined (_CRAY)
static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf)
{ return ecvt_r(x, n, pt, sign, buf); }
static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf)
{ return fcvt_r(x, n, pt, sign, buf); }
# if !defined (_STLP_NO_LONG_DOUBLE)
static inline char* _Stl_qecvtR(long double x, int n, int* pt, int* sign, char* buf)
{ return qecvt_r(x, n, pt, sign, buf); }
static inline char* _Stl_qfcvtR(long double x, int n, int* pt, int* sign, char* buf)
{ return qfcvt_r(x, n, pt, sign, buf); }
# endif
# elif defined (_STLP_MSVC_LIB) || defined (__MINGW32__) || defined (__BORLANDC__)
// those guys claim _cvt functions being reentrant.
# if defined (_STLP_USE_SAFE_STRING_FUNCTIONS)
# define _STLP_APPEND(a, b) a##b
# define _STLP_BUF_PARAMS , char* buf, size_t bsize
# define _STLP_SECURE_FUN(F, X, N, PT, SIGN) _STLP_APPEND(F, _s)(buf, bsize, X, N, PT, SIGN); return buf
# else
# define _STLP_CVT_DONT_NEED_BUF
# define _STLP_BUF_PARAMS
# define _STLP_SECURE_FUN(F, X, N, PT, SIGN) return F(X, N, PT, SIGN)
# endif
static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign _STLP_BUF_PARAMS)
{ _STLP_SECURE_FUN(_ecvt, x, n, pt, sign); }
static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign _STLP_BUF_PARAMS)
{ _STLP_SECURE_FUN(_fcvt, x, n, pt, sign); }
# if !defined (_STLP_NO_LONG_DOUBLE)
static inline char* _Stl_qecvtR(long double x, int n, int* pt, int* sign _STLP_BUF_PARAMS)
{ _STLP_SECURE_FUN(_ecvt, (double)x, n, pt, sign); }
static inline char* _Stl_qfcvtR(long double x, int n, int* pt, int* sign _STLP_BUF_PARAMS)
{ _STLP_SECURE_FUN(_fcvt, (double)x, n, pt, sign); }
# endif
# undef _STLP_SECURE_FUN
# undef _STLP_BUF_PARAMS
# undef _STLP_APPEND
# elif defined (__ISCPP__)
static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf)
{ return _fp_ecvt( x, n, pt, sign, buf); }
static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf)
{ return _fp_fcvt(x, n, pt, sign, buf); }
# if !defined (_STLP_NO_LONG_DOUBLE)
static inline char* _Stl_qecvtR(long double x, int n, int* pt, int* sign, char* buf)
{ return _fp_ecvt( x, n, pt, sign, buf); }
static inline char* _Stl_qfcvtR(long double x, int n, int* pt, int* sign, char* buf)
{ return _fp_fcvt(x, n, pt, sign, buf); }
# endif
# elif defined (__MRC__) || defined (__SC__) || defined (_CRAY)
static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* )
{ return ecvt( x, n, pt, sign ); }
static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* )
{ return fcvt(x, n, pt, sign); }
# if !defined (_STLP_NO_LONG_DOUBLE)
static inline char* _Stl_qecvtR(long double x, int n, int* pt, int* sign, char* )
{ return ecvt( x, n, pt, sign ); }
static inline char* _Stl_qfcvtR(long double x, int n, int* pt, int* sign, char* )
{ return fcvt(x, n, pt, sign); }
# endif
# endif
# if defined (_STLP_CVT_DONT_NEED_BUF)
# define _STLP_CVT_BUFFER(B)
# elif !defined (_STLP_USE_SAFE_STRING_FUNCTIONS)
# define _STLP_CVT_BUFFER(B) , B
# else
# define _STLP_CVT_BUFFER(B) , _STLP_ARRAY_AND_SIZE(B)
# endif
# if !defined (_STLP_USE_SAFE_STRING_FUNCTIONS)
# define _STLP_BUFFER(B) B
# else
# define _STLP_BUFFER(B) _STLP_ARRAY_AND_SIZE(B)
# endif
//----------------------------------------------------------------------
// num_put
// __format_float formats a mantissa and exponent as returned by
// one of the conversion functions (ecvt_r, fcvt_r, qecvt_r, qfcvt_r)
// according to the specified precision and format flags. This is
// based on doprnt but is much simpler since it is concerned only
// with floating point input and does not consider all formats. It
// also does not deal with blank padding, which is handled by
// __copy_float_and_fill.
static size_t __format_float_scientific( __iostring& buf, const char *bp,
int decpt, int sign, bool is_zero,
ios_base::fmtflags flags,
int precision, bool /* islong */)
{
// sign if required
if (sign)
buf += '-';
else if (flags & ios_base::showpos)
buf += '+';
// first digit of mantissa
buf += *bp++;
// start of grouping position, grouping won't occur in scientific notation
// as it is impossible to have something like 1234.0e04 but we return a correct
// group position for coherency with __format_float_fixed.
size_t __group_pos = buf.size();
// decimal point if required
if (precision != 0 || flags & ios_base::showpoint) {
buf += '.';
}
// rest of mantissa
int rz = precision;
while (rz-- > 0 && *bp != 0)
buf += *bp++;
// exponent
char expbuf[MAXESIZ + 2];
char *suffix = expbuf + MAXESIZ;
*suffix = 0;
if (!is_zero) {
int nn = decpt - 1;
if (nn < 0)
nn = -nn;
for (; nn > 9; nn /= 10)
*--suffix = (char) todigit(nn % 10);
*--suffix = (char) todigit(nn);
}
// prepend leading zeros to exponent
while (suffix > &expbuf[MAXESIZ - 2])
*--suffix = '0';
// put in the exponent sign
*--suffix = (char) ((decpt > 0 || is_zero ) ? '+' : '-');
// put in the e
*--suffix = flags & ios_base::uppercase ? 'E' : 'e';
// copy the suffix
buf += suffix;
return __group_pos;
}
static size_t __format_float_fixed( __iostring &buf, const char *bp,
int decpt, int sign, bool /* x */,
ios_base::fmtflags flags,
int precision, bool islong )
{
if ( sign && (decpt > -precision) && (*bp != 0) )
buf += '-';
else if ( flags & ios_base::showpos )
buf += '+';
int k = 0;
int maxfsig = islong ? 2*MAXFSIG : MAXFSIG;
// digits before decimal point
int nnn = decpt;
do {
buf += ((nnn <= 0 || *bp == 0 || k >= maxfsig) ? '0' : (++k, *bp++));
} while ( --nnn > 0 );
// start of grouping position
size_t __group_pos = buf.size();
// decimal point if needed
if ( flags & ios_base::showpoint || precision > 0 ) {
buf += '.';
}
// digits after decimal point if any
nnn = (min) (precision, MAXFCVT);
while ( --nnn >= 0 ) {
buf += (++decpt <= 0 || *bp == 0 || k >= maxfsig) ? '0' : (++k, *bp++);
}
// trailing zeros if needed
if ( precision > MAXFCVT ) {
buf.append( precision - MAXFCVT, '0' );
}
return __group_pos;
}
static void __format_nan_or_inf(__iostring& buf, double x, ios_base::fmtflags flags)
{
static const char* inf[2] = { "inf", "Inf" };
static const char* nan[2] = { "nan", "NaN" };
const char** inf_or_nan;
if (_Stl_is_inf(x)) { // Infinity
inf_or_nan = inf;
if (_Stl_is_neg_inf(x))
buf += '-';
else if (flags & ios_base::showpos)
buf += '+';
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -