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