C++ IsFloat function

前端 未结 18 1277
不思量自难忘°
不思量自难忘° 2020-12-09 15:58

Does anybody know of a convenient means of determining if a string value \"qualifies\" as a floating-point number?

bool IsFloat( string MyString )
{
   ... e         


        
相关标签:
18条回答
  • 2020-12-09 16:36

    Quick and dirty solution using std::stof:

    bool isFloat(const std::string& s) {
        try {
            std::stof(s);
            return true;
        } catch(...) {
            return false;
        }
    }
    
    0 讨论(0)
  • 2020-12-09 16:37

    it depends on the level of trust, you need and where the input data comes from. If the data comes from a user, you have to be more careful, as compared to imported table data, where you already know that all items are either integers or floats and only thats what you need to differentiate.

    For example, one of the fastest versions, would simply check for the presence of "." and "eE" in it. But then, you may want to look if the rest is being all digits. Skip whitespace at the beginning - but not in the middle, check for a single "." "eE" etc.

    Thus, the q&d fast hack will probably lead to a more sophisticated regEx-like (either call it or scan it yourself) approach. But then, how do you know, that the result - although looking like a float - can really be represented in your machine (i.e. try 1.2345678901234567890e1234567890). Of course, you can make a regEx with "up-to-N" digits in the mantissa/exponent, but thats machine/OS/compiler or whatever specific, sometimes.

    So, in the end, to be sure, you probably have to call for the underlying system's conversion and see what you get (exception, infinity or NAN).

    0 讨论(0)
  • 2020-12-09 16:38

    I was looking for something similar, found a much simpler answer than any I've seen (Although is for floats VS. ints, would still require a typecast from string)

    bool is_float(float val){
        if(val != floor(val)){
            return true;
        }
        else
            return false;
    }
    

    or:

    auto lambda_isFloat = [](float val) {return (val != floor(val)); };
    

    Hope this helps !

    ZMazz

    0 讨论(0)
  • 2020-12-09 16:41

    You could use atof and then have special handling for 0.0, but I don't think that counts as a particularly good solution.

    0 讨论(0)
  • 2020-12-09 16:42

    You may like Boost's lexical_cast (see http://www.boost.org/doc/libs/1_37_0/libs/conversion/lexical_cast.htm).

    bool isFloat(const std::string &someString)
    {
      using boost::lexical_cast;
      using boost::bad_lexical_cast; 
    
      try
      {
        boost::lexical_cast<float>(someString);
      }
      catch (bad_lexical_cast &)
      {
        return false;
      }
    
      return true;
    }
    

    You can use istream to avoid needing Boost, but frankly, Boost is just too good to leave out.

    0 讨论(0)
  • 2020-12-09 16:43

    The main issue with other responses is performance

    Often you don't need every corner case, for example maybe nan and -/+ inf, are not as important to cover as having speed. Maybe you don't need to handle 1.0E+03 notation. You just want a fast way to parse strings to numbers.

    Here is a simple, pure std::string way, that's not very fast:

    size_t npos = word.find_first_not_of ( ".+-0123456789" );
    if ( npos == std::string::npos ) {
       val = atof ( word.c_str() );
    }
    

    This is slow because it is O(k*13), checking each char against 0 thur 9

    Here is a faster way:

    bool isNum = true;
    int st = 0;
    while (word.at(st)==32) st++;    // leading spaces
    ch = word.at(st);
    if (ch == 43 || ch==45 ) st++;   // check +, -
    
    for (int n = st; n < word.length(); n++) {
      char ch = word.at(n);
      if ( ch < 48 || ch > 57 || ch != 46 ) {
         isNum = false;
         break;   // not a num, early terminate
      } 
    }
    

    This has the benefit of terminating early if any non-numerical character is found, and it checks by range rather than every number digit (0-9). So the average compares is 3x per char, O(k*3), with early termination.

    Notice this technique is very similar to the actual one used in the stdlib 'atof' function: http://www.beedub.com/Sprite093/src/lib/c/stdlib/atof.c

    0 讨论(0)
提交回复
热议问题