1 | // |
2 | // NumericString.h |
3 | // |
4 | // Library: Foundation |
5 | // Package: Core |
6 | // Module: NumericString |
7 | // |
8 | // Numeric string utility functions. |
9 | // |
10 | // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. |
11 | // and Contributors. |
12 | // |
13 | // SPDX-License-Identifier: BSL-1.0 |
14 | // |
15 | |
16 | |
17 | #ifndef Foundation_NumericString_INCLUDED |
18 | #define Foundation_NumericString_INCLUDED |
19 | |
20 | |
21 | #include "Poco/Foundation.h" |
22 | #include "Poco/Buffer.h" |
23 | #include "Poco/FPEnvironment.h" |
24 | #ifdef min |
25 | #undef min |
26 | #endif |
27 | #ifdef max |
28 | #undef max |
29 | #endif |
30 | #include <limits> |
31 | #include <cmath> |
32 | #include <cctype> |
33 | #if !defined(POCO_NO_LOCALE) |
34 | #include <locale> |
35 | #endif |
36 | |
37 | |
38 | #ifdef POCO_COMPILER_MSVC |
39 | #pragma warning(push) |
40 | #pragma warning(disable : 4146) |
41 | #endif // POCO_COMPILER_MSVC |
42 | |
43 | |
44 | // binary numbers are supported, thus 64 (bits) + 1 (string terminating zero) |
45 | #define POCO_MAX_INT_STRING_LEN 65 |
46 | // value from strtod.cc (double_conversion::kMaxSignificantDecimalDigits) |
47 | #define POCO_MAX_FLT_STRING_LEN 780 |
48 | |
49 | #define POCO_FLT_INF "inf" |
50 | #define POCO_FLT_NAN "nan" |
51 | #define POCO_FLT_EXP 'e' |
52 | |
53 | |
54 | namespace Poco { |
55 | |
56 | |
57 | namespace Impl { |
58 | |
59 | template<bool SIGNED, typename T> |
60 | class IsNegativeImpl; |
61 | |
62 | template<typename T> |
63 | class IsNegativeImpl<true, T> |
64 | { |
65 | public: |
66 | bool operator()(T x) { return x < 0; } |
67 | }; |
68 | |
69 | template<typename T> |
70 | class IsNegativeImpl<false, T> |
71 | { |
72 | public: |
73 | bool operator()(T /*x*/) { return false; } |
74 | }; |
75 | |
76 | } |
77 | |
78 | |
79 | template<typename T> |
80 | inline bool isNegative(T x) |
81 | { |
82 | using namespace Impl; |
83 | return IsNegativeImpl<std::numeric_limits<T>::is_signed, T>()(x); |
84 | } |
85 | |
86 | |
87 | template<typename To, typename From> |
88 | inline bool isIntOverflow(From val) |
89 | { |
90 | poco_assert_dbg (std::numeric_limits<From>::is_integer); |
91 | poco_assert_dbg (std::numeric_limits<To>::is_integer); |
92 | bool ret; |
93 | if (std::numeric_limits<To>::is_signed) |
94 | { |
95 | ret = (!std::numeric_limits<From>::is_signed && |
96 | (std::uintmax_t)val > (std::uintmax_t)INTMAX_MAX) || |
97 | (std::intmax_t)val < (std::intmax_t)std::numeric_limits<To>::min() || |
98 | (std::intmax_t)val > (std::intmax_t)std::numeric_limits<To>::max(); |
99 | } |
100 | else |
101 | { |
102 | ret = isNegative(val) || |
103 | (std::uintmax_t)val > (std::uintmax_t)std::numeric_limits<To>::max(); |
104 | } |
105 | return ret; |
106 | } |
107 | |
108 | |
109 | template <typename F, typename T> |
110 | inline T& isSafeIntCast(F from) |
111 | /// Returns true if it is safe to cast |
112 | /// integer from F to T. |
113 | { |
114 | if (!isIntOverflow<T, F>(from)) return true; |
115 | return false; |
116 | } |
117 | |
118 | |
119 | template <typename F, typename T> |
120 | inline T& safeIntCast(F from, T& to) |
121 | /// Returns csted value if it is safe |
122 | /// to cast integer from F to T, |
123 | /// otherwise throws BadCastException. |
124 | { |
125 | if (!isIntOverflow<T, F>(from)) |
126 | { |
127 | to = static_cast<T>(from); |
128 | return to; |
129 | } |
130 | throw BadCastException("safeIntCast: Integer overflow" ); |
131 | } |
132 | |
133 | inline char decimalSeparator() |
134 | /// Returns decimal separator from global locale or |
135 | /// default '.' for platforms where locale is unavailable. |
136 | { |
137 | #if !defined(POCO_NO_LOCALE) |
138 | return std::use_facet<std::numpunct<char> >(std::locale()).decimal_point(); |
139 | #else |
140 | return '.'; |
141 | #endif |
142 | } |
143 | |
144 | |
145 | inline char thousandSeparator() |
146 | /// Returns thousand separator from global locale or |
147 | /// default ',' for platforms where locale is unavailable. |
148 | { |
149 | #if !defined(POCO_NO_LOCALE) |
150 | return std::use_facet<std::numpunct<char> >(std::locale()).thousands_sep(); |
151 | #else |
152 | return ','; |
153 | #endif |
154 | } |
155 | |
156 | |
157 | // |
158 | // String to Number Conversions |
159 | // |
160 | |
161 | template <typename I> |
162 | bool strToInt(const char* pStr, I& outResult, short base, char thSep = ',') |
163 | /// Converts zero-terminated character array to integer number; |
164 | /// Thousand separators are recognized for base10 and current locale; |
165 | /// they are silently skipped and not verified for correct positioning. |
166 | /// It is not allowed to convert a negative number to unsigned integer. |
167 | /// |
168 | /// Function returns true if successful. If parsing was unsuccessful, |
169 | /// the return value is false with the result value undetermined. |
170 | { |
171 | poco_assert_dbg (base == 2 || base == 8 || base == 10 || base == 16); |
172 | |
173 | if (!pStr) return false; |
174 | while (std::isspace(*pStr)) ++pStr; |
175 | if (*pStr == '\0') return false; |
176 | bool negative = false; |
177 | if ((base == 10) && (*pStr == '-')) |
178 | { |
179 | if (!std::numeric_limits<I>::is_signed) return false; |
180 | negative = true; |
181 | ++pStr; |
182 | } |
183 | else if (*pStr == '+') ++pStr; |
184 | |
185 | // all numbers are parsed as positive; the sign |
186 | // for negative numbers is adjusted after parsing |
187 | ::uintmax_t limitCheck = std::numeric_limits<I>::max(); |
188 | if (negative) |
189 | { |
190 | poco_assert_dbg(std::numeric_limits<I>::is_signed); |
191 | // to cover the entire range, (-min > max) has to be |
192 | // taken into account; |
193 | // to avoid overflow for the largest int size, |
194 | // we resort to ::copysign() (ie. floating-point) |
195 | if (sizeof(I) == sizeof(::intmax_t)) |
196 | limitCheck = static_cast<::uintmax_t>(::copysign(std::numeric_limits<I>::min(), 1)); |
197 | else |
198 | { |
199 | ::intmax_t i = std::numeric_limits<I>::min(); |
200 | limitCheck = -i; |
201 | } |
202 | } |
203 | |
204 | std::uintmax_t result = 0; |
205 | for (; *pStr != '\0'; ++pStr) |
206 | { |
207 | if (result > (limitCheck / base)) return false; |
208 | switch (*pStr) |
209 | { |
210 | case '0': case '1': case '2': case '3': |
211 | case '4': case '5': case '6': case '7': |
212 | { |
213 | char add = (*pStr - '0'); |
214 | if ((limitCheck - result) < add) return false; |
215 | result = result * base + add; |
216 | } |
217 | break; |
218 | |
219 | case '8': case '9': |
220 | if ((base == 10) || (base == 0x10)) |
221 | { |
222 | char add = (*pStr - '0'); |
223 | if ((limitCheck - result) < add) return false; |
224 | result = result * base + add; |
225 | } |
226 | else return false; |
227 | |
228 | break; |
229 | |
230 | case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': |
231 | { |
232 | if (base != 0x10) return false; |
233 | char add = (*pStr - 'a'); |
234 | if ((limitCheck - result) < add) return false; |
235 | result = result * base + (10 + add); |
236 | } |
237 | break; |
238 | |
239 | case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': |
240 | { |
241 | if (base != 0x10) return false; |
242 | char add = (*pStr - 'A'); |
243 | if ((limitCheck - result) < add) return false; |
244 | result = result * base + (10 + add); |
245 | } |
246 | break; |
247 | |
248 | case '.': |
249 | if ((base == 10) && (thSep == '.')) break; |
250 | else return false; |
251 | |
252 | case ',': |
253 | if ((base == 10) && (thSep == ',')) break; |
254 | else return false; |
255 | |
256 | case ' ': |
257 | if ((base == 10) && (thSep == ' ')) break; |
258 | |
259 | default: |
260 | return false; |
261 | } |
262 | } |
263 | |
264 | if (negative && (base == 10)) |
265 | { |
266 | poco_assert_dbg(std::numeric_limits<I>::is_signed); |
267 | ::intmax_t i; |
268 | if (sizeof(I) == sizeof(::intmax_t)) |
269 | i = static_cast<::intmax_t>(::copysign(result, -1)); |
270 | else |
271 | i = static_cast<::intmax_t>(-result); |
272 | if (isIntOverflow<I>(i)) return false; |
273 | outResult = static_cast<I>(i); |
274 | } |
275 | else |
276 | { |
277 | if (isIntOverflow<I>(result)) return false; |
278 | outResult = static_cast<I>(result); |
279 | } |
280 | |
281 | return true; |
282 | } |
283 | |
284 | |
285 | template <typename I> |
286 | bool strToInt(const std::string& str, I& result, short base, char thSep = ',') |
287 | /// Converts string to integer number; |
288 | /// This is a wrapper function, for details see see the |
289 | /// bool strToInt(const char*, I&, short, char) implementation. |
290 | { |
291 | return strToInt(str.c_str(), result, base, thSep); |
292 | } |
293 | |
294 | |
295 | // |
296 | // Number to String Conversions |
297 | // |
298 | |
299 | namespace Impl { |
300 | |
301 | class Ptr |
302 | /// Utility char pointer wrapper class. |
303 | /// Class ensures increment/decrement remain within boundaries. |
304 | { |
305 | public: |
306 | Ptr(char* ptr, std::size_t offset): _beg(ptr), _cur(ptr), _end(ptr + offset) |
307 | { |
308 | } |
309 | |
310 | char*& operator ++ () // prefix |
311 | { |
312 | checkBounds(_cur + 1); |
313 | return ++_cur; |
314 | } |
315 | |
316 | char* operator ++ (int) // postfix |
317 | { |
318 | checkBounds(_cur + 1); |
319 | char* tmp = _cur++; |
320 | return tmp; |
321 | } |
322 | |
323 | char*& operator -- () // prefix |
324 | { |
325 | checkBounds(_cur - 1); |
326 | return --_cur; |
327 | } |
328 | |
329 | char* operator -- (int) // postfix |
330 | { |
331 | checkBounds(_cur - 1); |
332 | char* tmp = _cur--; |
333 | return tmp; |
334 | } |
335 | |
336 | char*& operator += (int incr) |
337 | { |
338 | checkBounds(_cur + incr); |
339 | return _cur += incr; |
340 | } |
341 | |
342 | char*& operator -= (int decr) |
343 | { |
344 | checkBounds(_cur - decr); |
345 | return _cur -= decr; |
346 | } |
347 | |
348 | operator char* () const |
349 | { |
350 | return _cur; |
351 | } |
352 | |
353 | std::size_t span() const |
354 | { |
355 | return _end - _beg; |
356 | } |
357 | |
358 | private: |
359 | void checkBounds(char* ptr) |
360 | { |
361 | if (ptr > _end) throw RangeException(); |
362 | } |
363 | |
364 | const char* _beg; |
365 | char* _cur; |
366 | const char* _end; |
367 | }; |
368 | |
369 | } // namespace Impl |
370 | |
371 | |
372 | template <typename T> |
373 | bool intToStr(T value, |
374 | unsigned short base, |
375 | char* result, |
376 | std::size_t& size, |
377 | bool prefix = false, |
378 | int width = -1, |
379 | char fill = ' ', |
380 | char thSep = 0) |
381 | /// Converts integer to string. Numeric bases from binary to hexadecimal are supported. |
382 | /// If width is non-zero, it pads the return value with fill character to the specified width. |
383 | /// When padding is zero character ('0'), it is prepended to the number itself; all other |
384 | /// paddings are prepended to the formatted result with minus sign or base prefix included |
385 | /// If prefix is true and base is octal or hexadecimal, respective prefix ('0' for octal, |
386 | /// "0x" for hexadecimal) is prepended. For all other bases, prefix argument is ignored. |
387 | /// Formatted string has at least [width] total length. |
388 | { |
389 | if (base < 2 || base > 0x10) |
390 | { |
391 | *result = '\0'; |
392 | return false; |
393 | } |
394 | |
395 | Impl::Ptr ptr(result, size); |
396 | int thCount = 0; |
397 | T tmpVal; |
398 | do |
399 | { |
400 | tmpVal = value; |
401 | value /= base; |
402 | *ptr++ = "FEDCBA9876543210123456789ABCDEF" [15 + (tmpVal - value * base)]; |
403 | if (thSep && (base == 10) && (++thCount == 3)) |
404 | { |
405 | *ptr++ = thSep; |
406 | thCount = 0; |
407 | } |
408 | } while (value); |
409 | |
410 | if ('0' == fill) |
411 | { |
412 | if (tmpVal < 0) --width; |
413 | if (prefix && base == 010) --width; |
414 | if (prefix && base == 0x10) width -= 2; |
415 | while ((ptr - result) < width) *ptr++ = fill; |
416 | } |
417 | |
418 | if (prefix && base == 010) *ptr++ = '0'; |
419 | else if (prefix && base == 0x10) |
420 | { |
421 | *ptr++ = 'x'; |
422 | *ptr++ = '0'; |
423 | } |
424 | |
425 | if (tmpVal < 0) *ptr++ = '-'; |
426 | |
427 | if ('0' != fill) |
428 | { |
429 | while ((ptr - result) < width) *ptr++ = fill; |
430 | } |
431 | |
432 | size = ptr - result; |
433 | poco_assert_dbg (size <= ptr.span()); |
434 | poco_assert_dbg ((-1 == width) || (size >= size_t(width))); |
435 | *ptr-- = '\0'; |
436 | |
437 | char* ptrr = result; |
438 | char tmp; |
439 | while(ptrr < ptr) |
440 | { |
441 | tmp = *ptr; |
442 | *ptr-- = *ptrr; |
443 | *ptrr++ = tmp; |
444 | } |
445 | |
446 | return true; |
447 | } |
448 | |
449 | |
450 | template <typename T> |
451 | bool uIntToStr(T value, |
452 | unsigned short base, |
453 | char* result, |
454 | std::size_t& size, |
455 | bool prefix = false, |
456 | int width = -1, |
457 | char fill = ' ', |
458 | char thSep = 0) |
459 | /// Converts unsigned integer to string. Numeric bases from binary to hexadecimal are supported. |
460 | /// If width is non-zero, it pads the return value with fill character to the specified width. |
461 | /// When padding is zero character ('0'), it is prepended to the number itself; all other |
462 | /// paddings are prepended to the formatted result with minus sign or base prefix included |
463 | /// If prefix is true and base is octal or hexadecimal, respective prefix ('0' for octal, |
464 | /// "0x" for hexadecimal) is prepended. For all other bases, prefix argument is ignored. |
465 | /// Formatted string has at least [width] total length. |
466 | { |
467 | if (base < 2 || base > 0x10) |
468 | { |
469 | *result = '\0'; |
470 | return false; |
471 | } |
472 | |
473 | Impl::Ptr ptr(result, size); |
474 | int thCount = 0; |
475 | T tmpVal; |
476 | do |
477 | { |
478 | tmpVal = value; |
479 | value /= base; |
480 | *ptr++ = "FEDCBA9876543210123456789ABCDEF" [15 + (tmpVal - value * base)]; |
481 | if (thSep && (base == 10) && (++thCount == 3)) |
482 | { |
483 | *ptr++ = thSep; |
484 | thCount = 0; |
485 | } |
486 | } while (value); |
487 | |
488 | if ('0' == fill) |
489 | { |
490 | if (prefix && base == 010) --width; |
491 | if (prefix && base == 0x10) width -= 2; |
492 | while ((ptr - result) < width) *ptr++ = fill; |
493 | } |
494 | |
495 | if (prefix && base == 010) *ptr++ = '0'; |
496 | else if (prefix && base == 0x10) |
497 | { |
498 | *ptr++ = 'x'; |
499 | *ptr++ = '0'; |
500 | } |
501 | |
502 | if ('0' != fill) |
503 | { |
504 | while ((ptr - result) < width) *ptr++ = fill; |
505 | } |
506 | |
507 | size = ptr - result; |
508 | poco_assert_dbg (size <= ptr.span()); |
509 | poco_assert_dbg ((-1 == width) || (size >= size_t(width))); |
510 | *ptr-- = '\0'; |
511 | |
512 | char* ptrr = result; |
513 | char tmp; |
514 | while(ptrr < ptr) |
515 | { |
516 | tmp = *ptr; |
517 | *ptr-- = *ptrr; |
518 | *ptrr++ = tmp; |
519 | } |
520 | |
521 | return true; |
522 | } |
523 | |
524 | template <typename T> |
525 | bool (T number, unsigned short base, std::string& result, bool prefix = false, int width = -1, char fill = ' ', char thSep = 0) |
526 | /// Converts integer to string; This is a wrapper function, for details see see the |
527 | /// bool intToStr(T, unsigned short, char*, int, int, char, char) implementation. |
528 | { |
529 | char res[POCO_MAX_INT_STRING_LEN] = { 0 }; |
530 | std::size_t size = POCO_MAX_INT_STRING_LEN; |
531 | bool ret = intToStr(number, base, res, size, prefix, width, fill, thSep); |
532 | result.assign(res, size); |
533 | return ret; |
534 | } |
535 | |
536 | |
537 | template <typename T> |
538 | std::string intToStr (T number, unsigned short base, bool prefix = false, int width = -1, char fill = ' ', char thSep = 0) |
539 | /// Converts integer to string; This is a wrapper function, for details see see the |
540 | /// bool intToStr(T, unsigned short, char*, int, int, char, char) implementation. |
541 | { |
542 | std::string result; |
543 | char res[POCO_MAX_INT_STRING_LEN] = {0}; |
544 | std::size_t size = POCO_MAX_INT_STRING_LEN; |
545 | const bool ret = intToStr(number, base, res, size, prefix, width, fill, thSep); |
546 | if (ret) result.assign(res, size); |
547 | return result; |
548 | } |
549 | |
550 | template <typename T> |
551 | bool (T number, unsigned short base, std::string& result, bool prefix = false, int width = -1, char fill = ' ', char thSep = 0) |
552 | /// Converts unsigned integer to string; This is a wrapper function, for details see see the |
553 | /// bool uIntToStr(T, unsigned short, char*, int, int, char, char) implementation. |
554 | { |
555 | char res[POCO_MAX_INT_STRING_LEN] = { 0 }; |
556 | std::size_t size = POCO_MAX_INT_STRING_LEN; |
557 | bool ret = uIntToStr(number, base, res, size, prefix, width, fill, thSep); |
558 | result.assign(res, size); |
559 | return ret; |
560 | } |
561 | |
562 | |
563 | template <typename T> |
564 | std::string uIntToStr (T number, unsigned short base, bool prefix = false, int width = -1, char fill = ' ', char thSep = 0) |
565 | /// Converts unsigned integer to string; This is a wrapper function, for details see see the |
566 | /// bool uIntToStr(T, unsigned short, char*, int, int, char, char) implementation. |
567 | { |
568 | std::string result; |
569 | char res[POCO_MAX_INT_STRING_LEN] = {0}; |
570 | std::size_t size = POCO_MAX_INT_STRING_LEN; |
571 | const bool ret = uIntToStr(number, base, res, size, prefix, width, fill, thSep); |
572 | if (ret) result.assign(res, size); |
573 | return result; |
574 | } |
575 | |
576 | |
577 | // |
578 | // Wrappers for double-conversion library (http://code.google.com/p/double-conversion/). |
579 | // |
580 | // Library is the implementation of the algorithm described in Florian Loitsch's paper: |
581 | // http://florian.loitsch.com/publications/dtoa-pldi2010.pdf |
582 | // |
583 | |
584 | |
585 | Foundation_API void floatToStr(char* buffer, |
586 | int bufferSize, |
587 | float value, |
588 | int lowDec = -std::numeric_limits<float>::digits10, |
589 | int highDec = std::numeric_limits<float>::digits10); |
590 | /// Converts a float value to string. Converted string must be shorter than bufferSize. |
591 | /// Conversion is done by computing the shortest string of digits that correctly represents |
592 | /// the input number. Depending on lowDec and highDec values, the function returns |
593 | /// decimal or exponential representation. |
594 | |
595 | Foundation_API void floatToFixedStr(char* buffer, |
596 | int bufferSize, |
597 | float value, |
598 | int precision); |
599 | /// Converts a float value to string. Converted string must be shorter than bufferSize. |
600 | /// Computes a decimal representation with a fixed number of digits after the |
601 | /// decimal point. |
602 | |
603 | |
604 | Foundation_API std::string& (std::string& str, |
605 | float value, |
606 | int precision = -1, |
607 | int width = 0, |
608 | char thSep = 0, |
609 | char decSep = 0); |
610 | /// Converts a float value, assigns it to the supplied string and returns the reference. |
611 | /// This function calls floatToStr(char*, int, float, int, int) and formats the result according to |
612 | /// precision (total number of digits after the decimal point, -1 means ignore precision argument) |
613 | /// and width (total length of formatted string). |
614 | |
615 | |
616 | Foundation_API std::string floatToStr(float value, |
617 | int precision = -1, |
618 | int width = 0, |
619 | char thSep = 0, |
620 | char decSep = 0); |
621 | /// Converts a float value, returns it to the supplied string. |
622 | /// This function calls floatToStr(char*, int, float, int, int) and formats the result according to |
623 | /// precision (total number of digits after the decimal point, -1 means ignore precision argument) |
624 | /// and width (total length of formatted string). |
625 | |
626 | |
627 | Foundation_API std::string& (std::string& str, |
628 | float value, |
629 | int precision, |
630 | int width = 0, |
631 | char thSep = 0, |
632 | char decSep = 0); |
633 | /// Converts a float value, assigns it to the supplied string and returns the reference. |
634 | /// This function calls floatToFixedStr(char*, int, float, int) and formats the result according to |
635 | /// precision (total number of digits after the decimal point) and width (total length of formatted string). |
636 | |
637 | |
638 | Foundation_API std::string floatToFixedStr(float value, |
639 | int precision, |
640 | int width = 0, |
641 | char thSep = 0, |
642 | char decSep = 0); |
643 | /// Converts a float value, returns it to the supplied string. |
644 | /// This function calls floatToFixedStr(char*, int, float, int) and formats the result according to |
645 | /// precision (total number of digits after the decimal point) and width (total length of formatted string). |
646 | |
647 | |
648 | Foundation_API void doubleToStr(char* buffer, |
649 | int bufferSize, |
650 | double value, |
651 | int lowDec = -std::numeric_limits<double>::digits10, |
652 | int highDec = std::numeric_limits<double>::digits10); |
653 | /// Converts a double value to string. Converted string must be shorter than bufferSize. |
654 | /// Conversion is done by computing the shortest string of digits that correctly represents |
655 | /// the input number. Depending on lowDec and highDec values, the function returns |
656 | /// decimal or exponential representation. |
657 | |
658 | |
659 | Foundation_API void doubleToFixedStr(char* buffer, |
660 | int bufferSize, |
661 | double value, |
662 | int precision); |
663 | /// Converts a double value to string. Converted string must be shorter than bufferSize. |
664 | /// Computes a decimal representation with a fixed number of digits after the |
665 | /// decimal point. |
666 | |
667 | |
668 | Foundation_API std::string& (std::string& str, |
669 | double value, |
670 | int precision = -1, |
671 | int width = 0, |
672 | char thSep = 0, |
673 | char decSep = 0); |
674 | /// Converts a double value, assigns it to the supplied string and returns the reference. |
675 | /// This function calls doubleToStr(char*, int, double, int, int) and formats the result according to |
676 | /// precision (total number of digits after the decimal point, -1 means ignore precision argument) |
677 | /// and width (total length of formatted string). |
678 | |
679 | |
680 | Foundation_API std::string doubleToStr(double value, |
681 | int precision = -1, |
682 | int width = 0, |
683 | char thSep = 0, |
684 | char decSep = 0); |
685 | /// Converts a double value, returns it to the supplied string. |
686 | /// This function calls doubleToStr(char*, int, double, int, int) and formats the result according to |
687 | /// precision (total number of digits after the decimal point, -1 means ignore precision argument) |
688 | /// and width (total length of formatted string). |
689 | |
690 | |
691 | Foundation_API std::string& (std::string& str, |
692 | double value, |
693 | int precision = -1, |
694 | int width = 0, |
695 | char thSep = 0, |
696 | char decSep = 0); |
697 | /// Converts a double value, assigns it to the supplied string and returns the reference. |
698 | /// This function calls doubleToFixedStr(char*, int, double, int) and formats the result according to |
699 | /// precision (total number of digits after the decimal point) and width (total length of formatted string). |
700 | |
701 | |
702 | Foundation_API std::string doubleToFixedStr(double value, |
703 | int precision = -1, |
704 | int width = 0, |
705 | char thSep = 0, |
706 | char decSep = 0); |
707 | /// Converts a double value, returns it to the supplied string. |
708 | /// This function calls doubleToFixedStr(char*, int, double, int) and formats the result according to |
709 | /// precision (total number of digits after the decimal point) and width (total length of formatted string). |
710 | |
711 | |
712 | Foundation_API float strToFloat(const char* str, |
713 | const char* inf = POCO_FLT_INF, const char* nan = POCO_FLT_NAN); |
714 | /// Converts the string of characters into single-precision floating point number. |
715 | /// Function uses double_convesrion::DoubleToStringConverter to do the conversion. |
716 | |
717 | |
718 | Foundation_API bool strToFloat(const std::string&, float& result, |
719 | char decSep = '.', char thSep = ',', |
720 | const char* inf = POCO_FLT_INF, const char* nan = POCO_FLT_NAN); |
721 | /// Converts the string of characters into single-precision floating point number. |
722 | /// The conversion result is assigned to the result parameter. |
723 | /// If decimal separator and/or thousand separator are different from defaults, they should be |
724 | /// supplied to ensure proper conversion. |
725 | /// |
726 | /// Returns true if successful, false otherwise. |
727 | |
728 | |
729 | Foundation_API double strToDouble(const char* str, |
730 | const char* inf = POCO_FLT_INF, const char* nan = POCO_FLT_NAN); |
731 | /// Converts the string of characters into double-precision floating point number. |
732 | |
733 | |
734 | Foundation_API bool strToDouble(const std::string& str, double& result, |
735 | char decSep = '.', char thSep = ',', |
736 | const char* inf = POCO_FLT_INF, const char* nan = POCO_FLT_NAN); |
737 | /// Converts the string of characters into double-precision floating point number. |
738 | /// The conversion result is assigned to the result parameter. |
739 | /// If decimal separator and/or thousand separator are different from defaults, they should be |
740 | /// supplied to ensure proper conversion. |
741 | /// |
742 | /// Returns true if successful, false otherwise. |
743 | |
744 | |
745 | } // namespace Poco |
746 | |
747 | |
748 | #ifdef POCO_COMPILER_MSVC |
749 | #pragma warning(pop) |
750 | #endif // POCO_COMPILER_MSVC |
751 | |
752 | |
753 | #endif // Foundation_NumericString_INCLUDED |
754 | |