8

is there any alternative to atof, strtod, lexical_cast, stringstream or sprintf?

that is:

  1. fast
  2. C++ way (std::string instead of char*)
  3. safe (no buffer overrun risk)
  4. valid (return NaN if conversion couldn't be made)
  5. no external library (independent)

I prefer more like this , a simple function, optimized, and to the point

reason :

  • atof and strtod is C function and they are not returning NaN upon failure, I prefer working on std::string, so I just asking if anyone already writing some wrapper to std::string that I can use (if you don't mind).
  • lexical_cast has boost dependency
  • stringstream is slow
  • sprintf has buffer overflow risk and its C function
Community
  • 1
  • 1
uray
  • 11,254
  • 13
  • 54
  • 74
  • 5
    I would suggest that you add some rationale of why you rule out the standard methods. There's no point giving a recommendation when you have arbitrarily discarded all the best ones (knowing that you can just wrap `atof` in a `std::string`-friendly function. – tenfour Sep 25 '11 at 21:03
  • 3
    You are converting floats to strings and you are worried about _performance_? What application do you have -- application, not synthetic benchmark -- where you can even notice that stringsteam is "slow"? – Nemo Sep 25 '11 at 21:20
  • I'am writing a library (or a wrapper) so it could be used for anything, and its slow by synthetic benchmark. – uray Sep 25 '11 at 21:27
  • What about `strtod(string.c_str(), NULL)` and `asprintf` to avoid buffer overruns? To be fair, I can't find any real, good reason to avoid C functions from C++ if they solve your problem. – zneak Sep 25 '11 at 21:59
  • @zneak: it does not return NaN if conversion wasn't succesful – uray Sep 25 '11 at 22:06
  • @uray, my first example with NULL as the second argument won't do it, but you can still verify that the conversion succeeded. See [this ideone snippet](http://ideone.com/8n1Ux) I just made. – zneak Sep 25 '11 at 22:51
  • Given the similarity, I would like to refer to an interesting discussion on [fast integer to string conversion](http://stackoverflow.com/questions/4351371/c-performance-challenge-integer-to-stdstring-conversion). In the end, the fastest parser is always a custom one that parses only a specific format and ignores other possible input formats and high-level constructs such as locales. – André Caron Sep 26 '11 at 00:34

3 Answers3

1

I'd look at Boost Spirit

At least the benchmarks of the formatters (that is float -> string) consistently turn out as top-of-the-bill*1*

Also the exact input format specification and semantics when parsing can be configured very nicely using a policy class.


Here is my absolute min-dependency use of qi::any_real_parser<> and the list of dependendencies it touches:

#include <boost/spirit/include/qi_real.hpp>

namespace qi = boost::spirit::qi;

int main()
{
    const char input[] = "3.1415926";
    const char *f(input);
    const char *l(f+strlen(input));

    qi::any_real_parser<double> x;
    double parsed;
    x.parse(f, l, qi::unused, qi::unused, parsed);

    return 0;
}

  • boost/concept
  • boost/config
  • boost/detail
  • boost/exception
  • boost/fusion
  • boost/iterator
  • boost/math
  • boost/mpl
  • boost/optional
  • boost/preprocessor
  • boost/proto
  • boost/range
  • boost/regex
  • boost/spirit
  • boost/typeof
  • boost/type_traits
  • boost/utility
  • boost/variant

aligned_storage.hpp,assert.hpp,blank_fwd.hpp,blank.hpp,call_traits.hpp,checked_delete.hpp,concept_check.hpp,config.hpp,cstdint.hpp,current_function.hpp,foreach_fwd.hpp,foreach.hpp,get_pointer.hpp,implicit_cast.hpp,iterator.hpp,limits.hpp,math_fwd.hpp,next_prior.hpp,noncopyable.hpp,none.hpp,none_t.hpp,optional.hpp,ref.hpp,static_assert.hpp,swap.hpp,throw_exception.hpp,type.hpp,utility.hpp,variant.hpp,version.hpp

1 e.g. http://www.boost.org/doc/libs/1_47_0/libs/spirit/doc/html/spirit/karma/performance_measurements/numeric_performance/double_performance.html

pmr
  • 58,701
  • 10
  • 113
  • 156
sehe
  • 374,641
  • 47
  • 450
  • 633
  • can I use it without boost dependency? – uray Sep 25 '11 at 21:08
  • What _is_ the boost dependency? Obviously, you'll need the boost/spirit/include/qi.hpp. But it's header only. It will probably bring in bits of mpl and fusion. So if you mean that, than no of course you can't use it without. – sehe Sep 25 '11 at 21:09
  • @uray: I don't understand the problem with the boost dependence. Suppose you come up with another library Q which does what you want, then obviously you would depend on library Q. You've already enumerated all the options which are available in the standard library. If the problem is that boost is too big, there are tools available which will extract out just the bits you need. (e.g. [`bcp`](http://www.boost.org/doc/libs/1_47_0/tools/bcp/doc/html/index.html)) – Billy ONeal Sep 25 '11 at 21:19
  • I'am simply asking for alternative, and I prefer not to add another dependent library to my library, if there's no alternative I could use boost or just create my own wrap to existing standard library – uray Sep 25 '11 at 21:30
  • in that case, roll your own or use strtod :) – sehe Sep 25 '11 at 21:51
1

If you want to convert from numerical types to std::string there's a std::to_string function available in the latest standard.

Unfortunately as I've found out recently, in Visual Studio 2010 it is somewhat limited because there are only three overloads available for it; long double, long long, and unsigned long long. This causes issues when trying to use them from within templates.

Dominik Grabiec
  • 10,315
  • 5
  • 39
  • 45
0

The fast format library should be able to do the kinds of transformations you're looking for, at least for writing a float out. It does not handle parsing of a float, however.

Billy ONeal
  • 104,103
  • 58
  • 317
  • 552
  • Erm... it doesn't handle parsing of a float :_) I looked that library up too because I hoped that by now they had support. No dice – sehe Sep 25 '11 at 21:36
  • @sehe: I did note that in my answer. – Billy ONeal Sep 25 '11 at 21:46
  • never mind, I somehow missed the fact that he wanted formatting as well. I should just have put the link in too :) – sehe Sep 25 '11 at 21:58