1e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott/* 2e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * Copyright (c) 1999 3e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * Silicon Graphics Computer Systems, Inc. 4e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * 5e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * Copyright (c) 1999 6e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * Boris Fomitchev 7e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * 8e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * This material is provided "as is", with absolutely no warranty expressed 9e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * or implied. Any use is at your own risk. 10e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * 11e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * Permission to use or copy this software for any purpose is hereby granted 12e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * without fee, provided the above notices are retained on all copies. 13e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * Permission to modify the code and to distribute modified code is granted, 14e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * provided the above notices are retained, and a notice that the code was 15e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * modified is included with the above copyright notice. 16e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * 17e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott */ 18e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 19e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#include "stlport_prefix.h" 20e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 21e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#include <cmath> 22e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#include <ios> 23e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#include <locale> 24e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 25e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if defined (__DECCXX) 26e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# define NDIG 400 27e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#else 28e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# define NDIG 82 29e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif 30e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 31e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#define todigit(x) ((x)+'0') 32e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 33e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if defined (_STLP_UNIX) 34e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 35e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# if defined (__sun) 36e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# include <floatingpoint.h> 37e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# endif 38e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 39e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# if defined (__sun) || defined (__digital__) || defined (__sgi) || defined (_STLP_SCO_OPENSERVER) || defined (__NCR_SVR) 40e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// DEC, SGI & Solaris need this 41e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# include <values.h> 42e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# include <nan.h> 43e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# endif 44e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 45e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# if defined (__QNXNTO__) || ( defined(__GNUC__) && defined(__APPLE__) ) || defined(_STLP_USE_UCLIBC) /* 0.9.26 */ || \ 46e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott defined(__FreeBSD__) 47e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# define USE_SPRINTF_INSTEAD 48e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# endif 49e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 50e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# if defined (_AIX) // JFA 3-Aug-2000 51e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# include <math.h> 52e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# include <float.h> 53e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# endif 54e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 55e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# include <math.h> 56e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif 57e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 58e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#include <cstdio> 59e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#include <cstdlib> 60e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 61e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if defined (_STLP_MSVC_LIB) || defined (__MINGW32__) || defined (__BORLANDC__) || defined (__DJGPP) || \ 62e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott defined (_STLP_SCO_OPENSERVER) || defined (__NCR_SVR) 63e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# include <float.h> 64e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif 65e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 66e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if defined (__MRC__) || defined (__SC__) || defined (_CRAY) //*TY 02/24/2000 - added support for MPW 67e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# include <fp.h> 68e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif 69e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 70e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if defined (__CYGWIN__) 71e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# include <ieeefp.h> 72e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif 73e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 74e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if defined (__MSL__) 75e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# include <cstdlib> // for atoi 76e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# include <cstdio> // for snprintf 77e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# include <algorithm> 78e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# include <cassert> 79e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif 80e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 81e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if defined (__ISCPP__) 82e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# include <cfloat> 83e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif 84e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 85e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#include <algorithm> 86e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 87e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if defined (__DMC__) 88e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# define snprintf _snprintf 89e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif 90e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 91e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_BEGIN_NAMESPACE 92e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 93e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_MOVE_TO_PRIV_NAMESPACE 94e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 95e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if defined (__MWERKS__) || defined(__BEOS__) 96e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# define USE_SPRINTF_INSTEAD 97e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif 98e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 99e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scotttemplate <int N> 100e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstruct _Dig 101e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ 102e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott enum { dig = _Dig<N/10>::dig + 1 }; 103e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott}; 104e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 105e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_TEMPLATE_NULL 106e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstruct _Dig<0> 107e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ 108e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott enum { dig = 0 }; 109e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott}; 110e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 111e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#ifdef _STLP_NO_LONG_DOUBLE 112e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# define MAXEDIGITS int(_Dig<DBL_MAX_10_EXP>::dig) 113e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# define MAXFSIG DBL_DIG 114e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# define MAXFCVT (DBL_DIG + 1) 115e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#else 116e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# define MAXEDIGITS int(_Dig<LDBL_MAX_10_EXP>::dig) 117e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# define MAXFSIG LDBL_DIG 118e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# define MAXFCVT (LDBL_DIG + 1) 119e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif 120e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 121e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// Tests for infinity and NaN differ on different OSs. We encapsulate 122e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// these differences here. 123e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if !defined (USE_SPRINTF_INSTEAD) 124e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# if defined (__hpux) && defined (__GNUC__) 125e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# define _STLP_USE_SIGN_HELPER 126e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# elif defined (__DJGPP) || (defined (_STLP_USE_GLIBC) && ! defined (__MSL__)) || \ 127e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott defined (__CYGWIN__) || \ 128e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || \ 129e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott defined (__HP_aCC) 130e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_nan_or_inf(double x) 131e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# if defined (isfinite) 132e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return !isfinite(x); } 133e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# else 134e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return !finite(x); } 135e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# endif 136e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_neg_nan(double x) { return isnan(x) && ( copysign(1., x) < 0 ); } 137e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_inf(double x) { return isinf(x); } 138e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// inline bool _Stl_is_neg_inf(double x) { return isinf(x) < 0; } 139e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_neg_inf(double x) { return isinf(x) && x < 0; } 140e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# elif (defined (__unix) || defined (__unix__)) && \ 141e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott !defined (__APPLE__) && !defined (__DJGPP) && !defined(__osf__) && \ 142e5b5bb96ec50350cad24fb9694f8399674535cd2Jing Yu !defined (_CRAY) && !defined (__ANDROID__) 143e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_nan_or_inf(double x) { return IsNANorINF(x); } 144e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_inf(double x) { return IsNANorINF(x) && IsINF(x); } 145e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_neg_inf(double x) { return (IsINF(x)) && (x < 0.0); } 146e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_neg_nan(double x) { return IsNegNAN(x); } 147e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# elif defined (_STLP_MSVC_LIB) || defined (__MINGW32__) || defined (__BORLANDC__) 148e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_nan_or_inf(double x) { return !_finite(x); } 149e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# if !defined (__BORLANDC__) 150e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_inf(double x) { 151e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott int fclass = _fpclass(x); 152e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return fclass == _FPCLASS_NINF || fclass == _FPCLASS_PINF; 153e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 154e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_neg_inf(double x) { return _fpclass(x) == _FPCLASS_NINF; } 155e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# else 156e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_inf(double x) { return _Stl_is_nan_or_inf(x) && !_isnan(x);} 157e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_neg_inf(double x) { return _Stl_is_inf(x) && x < 0 ; } 158e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# endif 159e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_neg_nan(double x) { return _isnan(x) && _copysign(1., x) < 0 ; } 160e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# if defined (__BORLANDC__) 161e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_nan_or_inf(long double x) { return !_finitel(x); } 162e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_inf(long double x) { return _Stl_is_nan_or_inf(x) && !_isnanl(x);} 163e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_neg_inf(long double x) { return _Stl_is_inf(x) && x < 0 ; } 164e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_neg_nan(long double x) { return _isnanl(x) && _copysignl(1.l, x) < 0 ; } 165e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# elif !defined (_STLP_NO_LONG_DOUBLE) 166e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// Simply there to avoid warning long double -> double implicit conversion: 167e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_nan_or_inf(long double x) { return _Stl_is_nan_or_inf(__STATIC_CAST(double, x)); } 168e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_inf(long double x) { return _Stl_is_inf(__STATIC_CAST(double, x));} 169e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_neg_inf(long double x) { return _Stl_is_neg_inf(__STATIC_CAST(double, x)); } 170e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_neg_nan(long double x) { return _Stl_is_neg_nan(__STATIC_CAST(double, x)); } 171e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# endif 172e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# elif defined (__MRC__) || defined (__SC__) || defined (__DMC__) 173e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic bool _Stl_is_nan_or_inf(double x) { return isnan(x) || !isfinite(x); } 174e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic bool _Stl_is_inf(double x) { return !isfinite(x); } 175e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic bool _Stl_is_neg_inf(double x) { return !isfinite(x) && signbit(x); } 176e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic bool _Stl_is_neg_nan(double x) { return isnan(x) && signbit(x); } 177e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# elif /* defined(__FreeBSD__) || defined(__OpenBSD__) || */ (defined(__GNUC__) && defined(__APPLE__)) 178e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_nan_or_inf(double x) { return !finite(x); } 179e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_inf(double x) { return _Stl_is_nan_or_inf(x) && ! isnan(x); } 180e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_neg_inf(double x) { return _Stl_is_inf(x) && x < 0 ; } 181e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_neg_nan(double x) { return isnan(x) && copysign(1., x) < 0 ; } 182e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# elif defined( _AIX ) // JFA 11-Aug-2000 183e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic bool _Stl_is_nan_or_inf(double x) { return isnan(x) || !finite(x); } 184e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic bool _Stl_is_inf(double x) { return !finite(x); } 185e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// bool _Stl_is_neg_inf(double x) { return _class(x) == FP_MINUS_INF; } 186e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic bool _Stl_is_neg_inf(double x) { return _Stl_is_inf(x) && ( copysign(1., x) < 0 ); } 187e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic bool _Stl_is_neg_nan(double x) { return isnan(x) && ( copysign(1., x) < 0 ); } 188e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# elif defined (__ISCPP__) 189e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_nan_or_inf (double x) { return _fp_isINF(x) || _fp_isNAN(x); } 190e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_inf (double x) { return _fp_isINF(x); } 191e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_neg_inf (double x) { return _fp_isINF(x) && x < 0; } 192e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_neg_nan (double x) { return _fp_isNAN(x) && x < 0; } 193e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# elif defined (_CRAY) 194e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# if defined (_CRAYIEEE) 195e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_nan_or_inf(double x) { return isnan(x) || isinf(x); } 196e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_inf(double x) { return isinf(x); } 197e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_neg_inf(double x) { return isinf(x) && signbit(x); } 198e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_neg_nan(double x) { return isnan(x) && signbit(x); } 199e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# else 200e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_nan_or_inf(double x) { return false; } 201e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_inf(double x) { return false; } 202e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_neg_inf(double x) { return false; } 203e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline bool _Stl_is_neg_nan(double x) { return false; } 204e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# endif 205e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# else // nothing from above 206e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# define USE_SPRINTF_INSTEAD 207e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# endif 208e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif // !USE_SPRINTF_INSTEAD 209e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 210e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if !defined (USE_SPRINTF_INSTEAD) 211e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// Reentrant versions of floating-point conversion functions. The argument 212e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// lists look slightly different on different operating systems, so we're 213e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// encapsulating the differences here. 214e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 215e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# if defined (__CYGWIN__) || defined(__DJGPP) 216e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf) 217e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return ecvtbuf(x, n, pt, sign, buf); } 218e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf) 219e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return fcvtbuf(x, n, pt, sign, buf); } 220e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# if !defined (_STLP_NO_LONG_DOUBLE) 221e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# if defined (__CYGWIN__) 222e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# define _STLP_EMULATE_LONG_DOUBLE_CVT 223e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# else 224e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_ecvtR(long double x, int n, int* pt, int* sign, char* buf) 225e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return ecvtbuf(x, n, pt, sign, buf); } 226e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_fcvtR(long double x, int n, int* pt, int* sign, char* buf) 227e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return fcvtbuf(x, n, pt, sign, buf); } 228e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# endif 229e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# endif 230e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# elif defined (_STLP_USE_GLIBC) 231e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf, size_t bsize) 232e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return ecvt_r(x, n, pt, sign, buf, bsize) == 0 ? buf : 0; } 233e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf, size_t bsize) 234e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return fcvt_r(x, n, pt, sign, buf, bsize) == 0 ? buf : 0; } 235e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# ifndef _STLP_NO_LONG_DOUBLE 236e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_ecvtR(long double x, int n, int* pt, int* sign, char* buf, size_t bsize) 237e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return qecvt_r(x, n, pt, sign, buf, bsize) == 0 ? buf : 0; } 238e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_fcvtR(long double x, int n, int* pt, int* sign, char* buf, size_t bsize) 239e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return qfcvt_r(x, n, pt, sign, buf, bsize) == 0 ? buf : 0; } 240e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# endif 241e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# define _STLP_NEED_CVT_BUFFER_SIZE 242e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# elif defined (__sun) 243e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf) 244e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return econvert(x, n, pt, sign, buf); } 245e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf) 246e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return fconvert(x, n, pt, sign, buf); } 247e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# ifndef _STLP_NO_LONG_DOUBLE 248e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_ecvtR(long double x, int n, int* pt, int* sign, char* buf) 249e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return qeconvert(&x, n, pt, sign, buf); } 250e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_fcvtR(long double x, int n, int* pt, int* sign, char* buf) 251e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return qfconvert(&x, n, pt, sign, buf); } 252e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# endif 253e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# elif defined (__DECCXX) 254e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf, size_t bsize) 255e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return (ecvt_r(x, n, pt, sign, buf, bsize) == 0 ? buf : 0); } 256e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf, size_t bsize) 257e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return (fcvt_r(x, n, pt, sign, buf, bsize) == 0 ? buf : 0); } 258e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# ifndef _STLP_NO_LONG_DOUBLE 259e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// fbp : no "long double" conversions ! 260e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_ecvtR(long double x, int n, int* pt, int* sign, char* buf, size_t bsize) 261e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return (ecvt_r((double)x, n, pt, sign, buf, bsize) == 0 ? buf : 0) ; } 262e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_fcvtR(long double x, int n, int* pt, int* sign, char* buf, size_t bsize) 263e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return (fcvt_r((double)x, n, pt, sign, buf, bsize) == 0 ? buf : 0); } 264e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# endif 265e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# define _STLP_NEED_CVT_BUFFER_SIZE 266e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# elif defined (__hpux) 267e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign) 268e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return ecvt(x, n, pt, sign); } 269e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign) 270e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return fcvt(x, n, pt, sign); } 271e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# if !defined (_STLP_NO_LONG_DOUBLE) 272e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_ecvtR(long double x, int n, int* pt, int* sign) 273e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return _ldecvt(*(long_double*)&x, n, pt, sign); } 274e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_fcvtR(long double x, int n, int* pt, int* sign) 275e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return _ldfcvt(*(long_double*)&x, n, pt, sign); } 276e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# endif 277e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# define _STLP_CVT_NEED_SYNCHRONIZATION 278e5b5bb96ec50350cad24fb9694f8399674535cd2Jing Yu# elif defined (__unix) && !defined (__APPLE__) && !defined (_CRAY) && \ 279e5b5bb96ec50350cad24fb9694f8399674535cd2Jing Yu !defined (__ANDROID__) 280e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf) 281e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return ecvt_r(x, n, pt, sign, buf); } 282e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf) 283e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return fcvt_r(x, n, pt, sign, buf); } 284e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# if !defined (_STLP_NO_LONG_DOUBLE) 285e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_ecvtR(long double x, int n, int* pt, int* sign, char* buf) 286e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return qecvt_r(x, n, pt, sign, buf); } 287e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_fcvtR(long double x, int n, int* pt, int* sign, char* buf) 288e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return qfcvt_r(x, n, pt, sign, buf); } 289e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# endif 290e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# elif defined (_STLP_MSVC_LIB) || defined (__MINGW32__) || defined (__BORLANDC__) 291e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# if defined (_STLP_USE_SAFE_STRING_FUNCTIONS) 292e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# define _STLP_APPEND(a, b) a##b 293e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# define _STLP_BUF_PARAMS , char* buf, size_t bsize 294e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# define _STLP_SECURE_FUN(F, X, N, PT, SIGN) _STLP_APPEND(F, _s)(buf, bsize, X, N, PT, SIGN); return buf 295e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# else 296e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# define _STLP_BUF_PARAMS 297e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# define _STLP_SECURE_FUN(F, X, N, PT, SIGN) return F(X, N, PT, SIGN) 298e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# define _STLP_CVT_NEED_SYNCHRONIZATION 299e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# endif 300e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign _STLP_BUF_PARAMS) 301e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ _STLP_SECURE_FUN(_ecvt, x, n, pt, sign); } 302e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign _STLP_BUF_PARAMS) 303e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ _STLP_SECURE_FUN(_fcvt, x, n, pt, sign); } 304e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# if !defined (_STLP_NO_LONG_DOUBLE) 305e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# if defined (_STLP_USE_SAFE_STRING_FUNCTIONS) 306e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# define _STLP_PARAMS , buf, bsize 307e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# else 308e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# define _STLP_PARAMS 309e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# endif 310e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_ecvtR(long double x, int n, int* pt, int* sign _STLP_BUF_PARAMS) 311e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return _Stl_ecvtR(__STATIC_CAST(double, x), n, pt, sign _STLP_PARAMS); } 312e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_fcvtR(long double x, int n, int* pt, int* sign _STLP_BUF_PARAMS) 313e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return _Stl_fcvtR(__STATIC_CAST(double, x), n, pt, sign _STLP_PARAMS); } 314e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# undef _STLP_PARAMS 315e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# endif 316e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# undef _STLP_SECURE_FUN 317e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# undef _STLP_BUF_PARAMS 318e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# undef _STLP_APPEND 319e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# if defined (__BORLANDC__) /* || defined (__GNUC__) MinGW do not support 'L' modifier so emulation do not work */ 320e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# define _STLP_EMULATE_LONG_DOUBLE_CVT 321e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# endif 322e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# elif defined (__ISCPP__) 323e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf) 324e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return _fp_ecvt( x, n, pt, sign, buf); } 325e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf) 326e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return _fp_fcvt(x, n, pt, sign, buf); } 327e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# if !defined (_STLP_NO_LONG_DOUBLE) 328e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_ecvtR(long double x, int n, int* pt, int* sign, char* buf) 329e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return _fp_ecvt( x, n, pt, sign, buf); } 330e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_fcvtR(long double x, int n, int* pt, int* sign, char* buf) 331e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return _fp_fcvt(x, n, pt, sign, buf); } 332e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# endif 333e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# elif defined (_AIX) || defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || \ 334e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott defined (__MRC__) || defined (__SC__) || defined (_CRAY) || \ 335e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott defined (_STLP_SCO_OPENSERVER) || defined (__NCR_SVR) || \ 336e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott defined (__DMC__) 337e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign) 338e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return ecvt(x, n, pt, sign ); } 339e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign) 340e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return fcvt(x, n, pt, sign); } 341e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# if !defined (_STLP_NO_LONG_DOUBLE) 342e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_ecvtR(long double x, int n, int* pt, int* sign) 343e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return ecvt(x, n, pt, sign ); } 344e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_fcvtR(long double x, int n, int* pt, int* sign) 345e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return fcvt(x, n, pt, sign); } 346e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# endif 347e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# define _STLP_CVT_NEED_SYNCHRONIZATION 348e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# else 349e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# error Missing _Stl_ecvtR and _Stl_fcvtR implementations. 350e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# endif 351e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 352e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if defined (_STLP_CVT_NEED_SYNCHRONIZATION) 353e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott/* STLport synchronize access to *cvt functions but those methods might 354e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * be called from outside, in this case we will still have a race condition. */ 355e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# if defined (_STLP_THREADS) 356e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic _STLP_STATIC_MUTEX& put_float_mutex() { 357e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static _STLP_STATIC_MUTEX __put_float_mutex _STLP_MUTEX_INITIALIZER; 358e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return __put_float_mutex; 359e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 360e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf) { 361e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott _STLP_auto_lock lock(put_float_mutex()); 362e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott strcpy(buf, _Stl_ecvtR(x, n, pt, sign)); return buf; 363e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 364e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf) { 365e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott _STLP_auto_lock lock(put_float_mutex()); 366e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott strcpy(buf, _Stl_fcvtR(x, n, pt, sign)); return buf; 367e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 368e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# if !defined (_STLP_NO_LONG_DOUBLE) && !defined (_STLP_EMULATE_LONG_DOUBLE_CVT) 369e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_ecvtR(long double x, int n, int* pt, int* sign, char* buf) { 370e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott _STLP_auto_lock lock(put_float_mutex()); 371e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott strcpy(buf, _Stl_ecvtR(x, n, pt, sign)); return buf; 372e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 373e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_fcvtR(long double x, int n, int* pt, int* sign, char* buf) { 374e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott _STLP_auto_lock lock(put_float_mutex()); 375e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott strcpy(buf, _Stl_fcvtR(x, n, pt, sign)); return buf; 376e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 377e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# endif 378e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# else 379e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char*) 380e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return _Stl_ecvtR(x, n, pt, sign); } 381e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char*) 382e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return _Stl_fcvtR(x, n, pt, sign); } 383e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# if !defined (_STLP_NO_LONG_DOUBLE) && !defined (_STLP_EMULATE_LONG_DOUBLE_CVT) 384e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_ecvtR(long double x, int n, int* pt, int* sign, char*) 385e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return _Stl_ecvtR(x, n, pt, sign); } 386e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline char* _Stl_fcvtR(long double x, int n, int* pt, int* sign, char*) 387e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott{ return _Stl_fcvtR(x, n, pt, sign); } 388e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# endif 389e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# endif 390e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif 391e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 392e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# if !defined (_STLP_USE_SAFE_STRING_FUNCTIONS) && !defined (_STLP_NEED_CVT_BUFFER_SIZE) 393e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# define _STLP_CVT_BUFFER(B) B 394e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# else 395e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# define _STLP_CVT_BUFFER(B) _STLP_ARRAY_AND_SIZE(B) 396e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# endif 397e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 398e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# if defined (_STLP_EMULATE_LONG_DOUBLE_CVT) 399e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic void __fill_fmtbuf(char* fmtbuf, ios_base::fmtflags flags, char long_modifier); 400e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 401e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// Emulation of ecvt/fcvt functions using sprintf: 402e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic char* _Stl_ecvtR(long double x, int n, int* pt, int* sign, char* buf) { 403e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // If long double value can be safely converted to double without losing precision 404e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // we use the ecvt function for double: 405e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott double y = __STATIC_CAST(double, x); 406e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (x == y) 407e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return _Stl_ecvtR(y, n, pt, sign, buf); 408e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 409e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott char fmtbuf[32]; 410e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott __fill_fmtbuf(fmtbuf, 0, 'L'); 411e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott sprintf(buf, fmtbuf, n, x < 0.0l ? -x : x); 412e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott /* We are waiting for something having the form x.xxxe+yyyy */ 413e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott *pt = 0; 414e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott *sign = 0; 415e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott int i = -1; 416e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott int offset = 0; 417e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott while (buf[++i] != 0 && n != 0) { 418e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (buf[i] >= '0' && buf[i] <= '9') { 419e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott --n; 420e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (offset != 0) 421e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott buf[i - offset] = buf[i]; 422e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 423e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott else { 424e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (offset != 0) break; 425e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott ++offset; 426e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott *pt = i; 427e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 428e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 429e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (offset != 0) 430e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott buf[i - offset] = 0; 431e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // Extract exponent part in point position: 432e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott int e = 0; 433e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott while (buf[++i] != 0) { 434e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (buf[i] >= '0' && buf[i] <= '9') { 435e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott e = e * 10 + (buf[i] - '0'); 436e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 437e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 438e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott *pt += e; 439e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return buf; 440e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 441e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 442e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic char* _Stl_fcvtR(long double x, int n, int* pt, int* sign, char* buf) { 443e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // If long double value can be safely converted to double without losing precision 444e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // we use the fcvt function for double: 445e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott double y = __STATIC_CAST(double, x); 446e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (x == y) 447e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return _Stl_fcvtR(y, n, pt, sign, buf); 448e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 449e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott char fmtbuf[32]; 450e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott __fill_fmtbuf(fmtbuf, ios_base::fixed, 'L'); 451e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott sprintf(buf, fmtbuf, n, x < 0.0l ? -x : x); 452e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott *pt = 0; 453e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott *sign = 0; 454e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott int i = -1; 455e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott int offset = 0; 456e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott while (buf[++i] != 0 && (offset == 0 || n != 0)) { 457e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (buf[i] >= '0' && buf[i] <= '9') { 458e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (offset != 0) { 459e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott --n; 460e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott buf[i - offset] = buf[i]; 461e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 462e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 463e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott else { 464e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott ++offset; 465e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott *pt = i; 466e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 467e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 468e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (offset != 0) 469e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott buf[i - offset] = 0; 470e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott else 471e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott *pt = i; 472e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return buf; 473e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 474e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif 475e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 476e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott//---------------------------------------------------------------------- 477e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// num_put 478e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 479e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// __format_float formats a mantissa and exponent as returned by 480e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// one of the conversion functions (ecvt_r, fcvt_r, qecvt_r, qfcvt_r) 481e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// according to the specified precision and format flags. This is 482e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// based on doprnt but is much simpler since it is concerned only 483e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// with floating point input and does not consider all formats. It 484e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// also does not deal with blank padding, which is handled by 485e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// __copy_float_and_fill. 486e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 487e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic size_t __format_float_scientific( __iostring& buf, const char *bp, 488e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott int decpt, int sign, bool is_zero, 489e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott ios_base::fmtflags flags, 490e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott int precision) { 491e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // sign if required 492e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (sign) 493e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott buf += '-'; 494e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott else if (flags & ios_base::showpos) 495e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott buf += '+'; 496e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 497e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // first digit of mantissa 498e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott buf += *bp++; 499e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 500e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // start of grouping position, grouping won't occur in scientific notation 501e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // as it is impossible to have something like 1234.0e04 but we return a correct 502e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // group position for coherency with __format_float_fixed. 503e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott size_t __group_pos = buf.size(); 504e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 505e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // decimal point if required 506e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (precision != 0 || flags & ios_base::showpoint) { 507e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott buf += '.'; 508e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 509e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 510e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // rest of mantissa 511e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott while (*bp != 0 && precision--) 512e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott buf += *bp++; 513e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 514e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // trailing 0 if needed 515e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (precision > 0) 516e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott buf.append(precision, '0'); 517e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 518e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // exponent size = number of digits + exponent sign + exponent symbol + trailing zero 519e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott char expbuf[MAXEDIGITS + 3]; 520e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott //We start filling at the buffer end 521e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott char *suffix = expbuf + MAXEDIGITS + 2; 522e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott *suffix = 0; 523e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (!is_zero) { 524e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott int nn = decpt - 1; 525e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (nn < 0) 526e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott nn = -nn; 527e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott for (; nn > 9; nn /= 10) 528e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott *--suffix = (char) todigit(nn % 10); 529e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott *--suffix = (char) todigit(nn); 530e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 531e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 532e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // prepend leading zeros to exponent 533e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // C89 Standard says that it should be at least 2 digits, C99 Standard says that 534e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // we stop prepend zeros if more than 3 digits. To repect both STLport prepend zeros 535e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // until it is 2 digits. 536e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott while (suffix > &expbuf[MAXEDIGITS]) 537e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott *--suffix = '0'; 538e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 539e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // put in the exponent sign 540e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott *--suffix = (char) ((decpt > 0 || is_zero ) ? '+' : '-'); 541e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 542e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // put in the e 543e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott *--suffix = flags & ios_base::uppercase ? 'E' : 'e'; 544e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 545e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // copy the suffix 546e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott buf += suffix; 547e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return __group_pos; 548e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 549e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 550e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic size_t __format_float_fixed( __iostring &buf, const char *bp, 551e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott int decpt, int sign, 552e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott ios_base::fmtflags flags, 553e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott int precision) { 554e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if ( sign && (decpt > -precision) && (*bp != 0) ) 555e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott buf += '-'; 556e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott else if ( flags & ios_base::showpos ) 557e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott buf += '+'; 558e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 559e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // digits before decimal point 560e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott int nnn = decpt; 561e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott do { 562e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott buf += (nnn <= 0 || *bp == 0) ? '0' : *bp++; 563e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } while ( --nnn > 0 ); 564e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 565e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // start of grouping position 566e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott size_t __group_pos = buf.size(); 567e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 568e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // decimal point if needed 569e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if ( flags & ios_base::showpoint || precision > 0 ) { 570e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott buf += '.'; 571e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 572e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 573e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // digits after decimal point if any 574e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott while ( *bp != 0 && --precision >= 0 ) { 575e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott buf += (++decpt <= 0) ? '0' : *bp++; 576e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 577e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 578e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // trailing zeros if needed 579e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (precision > 0) 580e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott buf.append(precision, '0'); 581e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 582e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return __group_pos; 583e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 584e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 585e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if defined (_STLP_USE_SIGN_HELPER) 586e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scotttemplate<class _FloatT> 587e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstruct float_sign_helper { 588e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott float_sign_helper(_FloatT __x) 589e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott { _M_number._num = __x; } 590e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 591e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott bool is_negative() const { 592e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott const unsigned short sign_mask(1 << (sizeof(unsigned short) * CHAR_BIT - 1)); 593e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return (get_sign_word() & sign_mask) != 0; 594e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 595e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottprivate: 596e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott union { 597e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott unsigned short _Words[8]; 598e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott _FloatT _num; 599e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } _M_number; 600e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 601e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott unsigned short get_word_higher() const _STLP_NOTHROW 602e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott { return _M_number._Words[0]; } 603e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott unsigned short get_word_lower() const _STLP_NOTHROW 604e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott { return _M_number._Words[(sizeof(_FloatT) >= 12 ? 10 : sizeof(_FloatT)) / sizeof(unsigned short) - 1]; } 605e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott unsigned short get_sign_word() const _STLP_NOTHROW 606e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# if defined (_STLP_BIG_ENDIAN) 607e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott { return get_word_higher(); } 608e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# else /* _STLP_LITTLE_ENDIAN */ 609e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott { return get_word_lower(); } 610e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# endif 611e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott}; 612e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif 613e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 614e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scotttemplate <class _FloatT> 615e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic size_t __format_nan_or_inf(__iostring& buf, _FloatT x, ios_base::fmtflags flags) { 616e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static const char* inf[2] = { "inf", "Inf" }; 617e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static const char* nan[2] = { "nan", "NaN" }; 618e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott const char** inf_or_nan; 619e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if !defined (_STLP_USE_SIGN_HELPER) 620e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (_Stl_is_inf(x)) { // Infinity 621e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott inf_or_nan = inf; 622e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (_Stl_is_neg_inf(x)) 623e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott buf += '-'; 624e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott else if (flags & ios_base::showpos) 625e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott buf += '+'; 626e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } else { // NaN 627e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott inf_or_nan = nan; 628e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (_Stl_is_neg_nan(x)) 629e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott buf += '-'; 630e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott else if (flags & ios_base::showpos) 631e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott buf += '+'; 632e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 633e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#else 634e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott typedef numeric_limits<_FloatT> limits; 635e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (x == limits::infinity() || x == -limits::infinity()) { 636e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott inf_or_nan = inf; 637e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } else { // NaN 638e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott inf_or_nan = nan; 639e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 640e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott float_sign_helper<_FloatT> helper(x); 641e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (helper.is_negative()) 642e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott buf += '-'; 643e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott else if (flags & ios_base::showpos) 644e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott buf += '+'; 645e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif 646e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott size_t ret = buf.size(); 647e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott buf += inf_or_nan[flags & ios_base::uppercase ? 1 : 0]; 648e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return ret; 649e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 650e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 651e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic inline size_t __format_float(__iostring &buf, const char * bp, 652e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott int decpt, int sign, bool is_zero, 653e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott ios_base::fmtflags flags, 654e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott int precision) { 655e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott size_t __group_pos = 0; 656e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott switch (flags & ios_base::floatfield) { 657e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott case ios_base::scientific: 658e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott __group_pos = __format_float_scientific( buf, bp, decpt, sign, is_zero, 659e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott flags, precision); 660e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott break; 661e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott case ios_base::fixed: 662e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott __group_pos = __format_float_fixed( buf, bp, decpt, sign, 663e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott flags, precision); 664e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott break; 665e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott default: // g format 666e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // establish default precision 667e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (flags & ios_base::showpoint || precision > 0) { 668e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (precision == 0) precision = 1; 669e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } else 670e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott precision = 6; 671e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 672e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // reset exponent if value is zero 673e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (is_zero) 674e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott decpt = 1; 675e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 676e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott int kk = precision; 677e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (!(flags & ios_base::showpoint)) { 678e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott size_t n = strlen(bp); 679e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (n < (size_t)kk) 680e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott kk = (int)n; 681e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott while (kk >= 1 && bp[kk-1] == '0') 682e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott --kk; 683e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 684e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 685e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (decpt < -3 || decpt > precision) { 686e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott precision = kk - 1; 687e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott __group_pos = __format_float_scientific( buf, bp, decpt, sign, is_zero, 688e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott flags, precision); 689e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } else { 690e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott precision = kk - decpt; 691e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott __group_pos = __format_float_fixed( buf, bp, decpt, sign, 692e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott flags, precision); 693e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 694e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott break; 695e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } /* switch */ 696e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return __group_pos; 697e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 698e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 699e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif 700e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 701e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if defined (USE_SPRINTF_INSTEAD) || defined (_STLP_EMULATE_LONG_DOUBLE_CVT) 702e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstruct GroupPos { 703e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott bool operator () (char __c) const { 704e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return __c == '.' || 705e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott __c == 'e' || __c == 'E'; 706e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 707e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott}; 708e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 709e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// Creates a format string for sprintf() 710e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic void __fill_fmtbuf(char* fmtbuf, ios_base::fmtflags flags, char long_modifier) { 711e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott fmtbuf[0] = '%'; 712e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott int i = 1; 713e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 714e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (flags & ios_base::showpos) 715e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott fmtbuf[i++] = '+'; 716e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 717e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (flags & ios_base::showpoint) 718e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott fmtbuf[i++] = '#'; 719e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 720e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott fmtbuf[i++] = '.'; 721e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott fmtbuf[i++] = '*'; 722e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 723e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (long_modifier) 724e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott fmtbuf[i++] = long_modifier; 725e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 726e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott switch (flags & ios_base::floatfield) 727e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott { 728e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott case ios_base::scientific: 729e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott fmtbuf[i++] = (flags & ios_base::uppercase) ? 'E' : 'e'; 730e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott break; 731e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott case ios_base::fixed: 732e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# if defined (__FreeBSD__) 733e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott fmtbuf[i++] = 'f'; 734e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# else 735e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott fmtbuf[i++] = (flags & ios_base::uppercase) ? 'F' : 'f'; 736e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# endif 737e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott break; 738e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott default: 739e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott fmtbuf[i++] = (flags & ios_base::uppercase) ? 'G' : 'g'; 740e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott break; 741e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 742e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 743e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott fmtbuf[i] = 0; 744e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 745e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 746e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif /* USE_SPRINTF_INSTEAD */ 747e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 748e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scotttemplate <class _FloatT> 749e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic size_t __write_floatT(__iostring &buf, ios_base::fmtflags flags, int precision, 750e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott _FloatT x 751e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if defined (USE_SPRINTF_INSTEAD) 752e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott , char modifier) { 753e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott /* In theory, if we want 'arbitrary' precision, we should use 'arbitrary' 754e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * buffer size below, but really we limited by exponent part in double. 755e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * - ptr 756e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott */ 757e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott typedef numeric_limits<_FloatT> limits; 758e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott char static_buf[limits::max_exponent10 + 6]; // 6: -xxx.yyyE-zzz (sign, dot, E, exp sign, \0) 759e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott char fmtbuf[32]; 760e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott __fill_fmtbuf(fmtbuf, flags, modifier); 761e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott snprintf(_STLP_ARRAY_AND_SIZE(static_buf), fmtbuf, precision, x); 762e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott buf = static_buf; 763e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return find_if(buf.begin(), buf.end(), GroupPos()) - buf.begin(); 764e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#else 765e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott ) { 766e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott typedef numeric_limits<_FloatT> limits; 767e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott //If numeric_limits support is correct we use the exposed values to detect NaN and infinity: 768e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (limits::has_infinity && limits::has_quiet_NaN) { 769e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (!(x == x) || // NaN check 770e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott (x == limits::infinity() || x == -limits::infinity())) { 771e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return __format_nan_or_inf(buf, x, flags); 772e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 773e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 774e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // numeric_limits support is not good enough, we rely on platform dependent function 775e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // _Stl_is_nan_or_inf that do not support long double. 776e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott else if (_Stl_is_nan_or_inf(x)) { 777e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return __format_nan_or_inf(buf, x, flags); 778e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 779e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# if defined (__MINGW32__) 780e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott //For the moment MinGW is limited to display at most numeric_limits<double>::max() 781e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (x > numeric_limits<double>::max() || 782e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott x < -numeric_limits<double>::max()) { 783e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return __format_nan_or_inf(buf, x, flags); 784e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 785e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# endif 786e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 787e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott /* Buffer size is max number of digits which is the addition of: 788e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * - max_exponent10: max number of digits in fixed mode 789e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * - digits10 + 2: max number of significant digits 790e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * - trailing '\0' 791e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott */ 792e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott char cvtbuf[limits::max_exponent10 + limits::digits10 + 2 + 1]; 793e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott char *bp; 794e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott int decpt, sign; 795e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 796e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott switch (flags & ios_base::floatfield) { 797e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott case ios_base::fixed: 798e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott { 799e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott /* Here, number of digits represents digits _after_ decimal point. 800e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * In order to limit static buffer size we have to give 2 different values depending on x value. 801e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * For small values (abs(x) < 1) we need as many digits as requested by precision limited by the maximum number of digits 802e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * which is min_exponent10 + digits10 + 2 803e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * For bigger values we won't have more than limits::digits10 + 2 digits after decimal point. */ 804e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott int digits10 = (x > -1.0 && x < 1.0 ? -limits::min_exponent10 + limits::digits10 + 2 805e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott : limits::digits10 + 2); 806e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott bp = _Stl_fcvtR(x, (min) (precision, digits10), &decpt, &sign, _STLP_CVT_BUFFER(cvtbuf) ); 807e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 808e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott break; 809e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott case ios_base::scientific: 810e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott default: 811e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott /* Here, number of digits is total number of digits which is limited to digits10 + 2. */ 812e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott { 813e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott int digits10 = limits::digits10 + 2; 814e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott bp = _Stl_ecvtR(x, (min) (precision, digits10), &decpt, &sign, _STLP_CVT_BUFFER(cvtbuf) ); 815e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 816e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott break; 817e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 818e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return __format_float(buf, bp, decpt, sign, x == 0.0, flags, precision); 819e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif 820e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 821e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 822e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottsize_t _STLP_CALL 823e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott__write_float(__iostring &buf, ios_base::fmtflags flags, int precision, 824e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott double x) { 825e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return __write_floatT(buf, flags, precision, x 826e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if defined (USE_SPRINTF_INSTEAD) 827e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott , 0 828e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif 829e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott ); 830e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 831e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 832e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if !defined (_STLP_NO_LONG_DOUBLE) 833e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottsize_t _STLP_CALL 834e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott__write_float(__iostring &buf, ios_base::fmtflags flags, int precision, 835e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott long double x) { 836e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return __write_floatT(buf, flags, precision, x 837e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if defined (USE_SPRINTF_INSTEAD) 838e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott , 'L' 839e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif 840e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott ); 841e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 842e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif 843e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 844e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottvoid _STLP_CALL __get_floor_digits(__iostring &out, _STLP_LONGEST_FLOAT_TYPE __x) { 845e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott typedef numeric_limits<_STLP_LONGEST_FLOAT_TYPE> limits; 846e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if defined (USE_SPRINTF_INSTEAD) 847e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott char cvtbuf[limits::max_exponent10 + 6]; 848e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# if !defined (_STLP_NO_LONG_DOUBLE) 849e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott snprintf(_STLP_ARRAY_AND_SIZE(cvtbuf), "%Lf", __x); // check for 1234.56! 850e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# else 851e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott snprintf(_STLP_ARRAY_AND_SIZE(cvtbuf), "%f", __x); // check for 1234.56! 852e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# endif 853e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott char *p = strchr( cvtbuf, '.' ); 854e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if ( p == 0 ) { 855e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott out.append( cvtbuf ); 856e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } else { 857e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott out.append( cvtbuf, p ); 858e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 859e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#else 860e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott char cvtbuf[limits::max_exponent10 + 1]; 861e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott char * bp; 862e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott int decpt, sign; 863e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott bp = _Stl_fcvtR(__x, 0, &decpt, &sign, _STLP_CVT_BUFFER(cvtbuf)); 864e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 865e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (sign) { 866e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott out += '-'; 867e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 868e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott out.append(bp, bp + decpt); 869e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif 870e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 871e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 872e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 873e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if !defined (_STLP_NO_WCHAR_T) 874e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottvoid _STLP_CALL __convert_float_buffer( __iostring const& str, __iowstring &out, 875e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott const ctype<wchar_t>& ct, wchar_t dot, bool __check_dot) { 876e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott string::const_iterator str_ite(str.begin()), str_end(str.end()); 877e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 878e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott //First loop, check the dot char 879e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (__check_dot) { 880e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott while (str_ite != str_end) { 881e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (*str_ite != '.') { 882e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott out += ct.widen(*str_ite++); 883e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } else { 884e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott out += dot; 885e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott break; 886e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 887e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 888e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } else { 889e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (str_ite != str_end) { 890e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott out += ct.widen(*str_ite); 891e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 892e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 893e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 894e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (str_ite != str_end) { 895e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott //Second loop, dot has been found, no check anymore 896e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott while (++str_ite != str_end) { 897e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott out += ct.widen(*str_ite); 898e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 899e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 900e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 901e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 902e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif 903e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 904e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottvoid _STLP_CALL 905e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott__adjust_float_buffer(__iostring &str, char dot) { 906e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if ('.' != dot) { 907e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott size_t __dot_pos = str.find('.'); 908e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (__dot_pos != string::npos) { 909e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott str[__dot_pos] = dot; 910e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 911e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 912e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 913e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 914e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_MOVE_TO_STD_NAMESPACE 915e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott_STLP_END_NAMESPACE 916e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 917e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// Local Variables: 918e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// mode:C++ 919e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// End: 920