diff --git a/lib/mathlib.cpp b/lib/mathlib.cpp index 509b01993..6fb7d61d2 100644 --- a/lib/mathlib.cpp +++ b/lib/mathlib.cpp @@ -66,7 +66,7 @@ MathLib::bigint MathLib::toLongNumber(const std::string &str) return ret; } - if (str.find_first_of("eE") != std::string::npos) + if (isFloat(str)) return static_cast(std::atof(str.c_str())); bigint ret = 0; @@ -106,9 +106,43 @@ bool MathLib::isFloat(const std::string &s) // every number that contains a . is a float if (s.find("." , 0) != std::string::npos) return true; - // scientific notation - return (s.find("E-", 0) != std::string::npos - || s.find("e-", 0) != std::string::npos); + // scientific notation (without dot!) + std::string::const_iterator it=s.begin(); + if (*it=='+' || *it=='-') { // mantissa sign char + ++it; + if (it == s.end()) + return false; + } + if (!std::isdigit(*it)) + return false; + ++it; + while (std::isdigit(*it)) { // number + ++it; + if (it == s.end()) + return false; + } + if (*it!='e' && *it!='E') + return false; + else + ++it; + if (it == s.end()) + return false; // incomplete exponent number + if (*it=='+' || *it=='-') { // exponent sign char + ++it; + if (it == s.end()) + return false; // incomplete exponent number + } + + while (std::isdigit(*it)) { // number + ++it; + if (it == s.end()) + return true; + } + if (it==s.end()) + return true; + if ((*it=='f' || *it=='F') && (it+1)==s.end()) // trailing 'f'/'F' to indicate a float literal (as opposed to a double literal) + return true; + return false; } bool MathLib::isNegative(const std::string &s) @@ -149,15 +183,13 @@ bool MathLib::isInt(const std::string & s) // perform prechecks: // ------------------ // first check, if a point is found, it is an floating point value - if (s.find(".", 0) != std::string::npos) return false; - // check for scientific notation e.g. NumberE-Number this is obvious an floating point value - else if (s.find("E-", 0) != std::string::npos || s.find("e-", 0) != std::string::npos) return false; - + const std::string charsToIndicateAFloat=".eE"; + if (s.find_last_of(charsToIndicateAFloat) != std::string::npos) + return false; // prechecking has nothing found,... // gather information enum Representation { - eScientific = 0, // NumberE+Number or NumberENumber eOctal, // starts with 0 eHex, // starts with 0x eDefault // Numbers with a (possible) trailing u or U or l or L for unsigned or long datatypes @@ -172,9 +204,7 @@ bool MathLib::isInt(const std::string & s) while (std::isspace(s[n])) ++n; // determine type - if (s.find("E", 0) != std::string::npos) { - Mode = eScientific; - } else if (isHex(s)) { + if (isHex(s)) { Mode = eHex; } else if (isOct(s)) { Mode = eOctal; @@ -183,24 +213,7 @@ bool MathLib::isInt(const std::string & s) // check sign if (s[n] == '-' || s[n] == '+') ++n; - // check scientific notation - if (Mode == eScientific) { - // check digits - while (std::isdigit(s[n])) ++n; - - // check scientific notation - if (std::tolower(s[n]) == 'e') { - ++n; - // check positive exponent - if (s[n] == '+') ++n; - // floating pointer number e.g. 124E-2 - if (s[n] == '-') return false; - // check digits of the exponent - while (std::isdigit(s[n])) ++n; - } - } - // check hex notation - else if (Mode == eHex) { + if (Mode == eHex) { ++n; // 0 ++n; // x while (std::isxdigit(s[n])) diff --git a/test/testmathlib.cpp b/test/testmathlib.cpp index 34bb257f2..f593714e1 100644 --- a/test/testmathlib.cpp +++ b/test/testmathlib.cpp @@ -107,8 +107,8 @@ private: // multiply ASSERT_EQUALS("-0.003" , MathLib::multiply("-1e-3", "3")); ASSERT_EQUALS("-11.96" , MathLib::multiply("-2.3", "5.2")); - ASSERT_EQUALS("3000" , MathLib::multiply("1E3", "3")); - ASSERT_EQUALS("3000" , MathLib::multiply("1E+3", "3")); + ASSERT_EQUALS("3000.0" , MathLib::multiply("1E3", "3")); + ASSERT_EQUALS("3000.0" , MathLib::multiply("1E+3", "3")); ASSERT_EQUALS("3000.0" , MathLib::multiply("1.0E3", "3")); ASSERT_EQUALS("-3000.0" , MathLib::multiply("-1.0E3", "3")); ASSERT_EQUALS("-3000.0" , MathLib::multiply("-1.0E+3", "3")); @@ -252,10 +252,10 @@ private: ASSERT_EQUALS(true , MathLib::isInt("1")); ASSERT_EQUALS(true , MathLib::isInt("-1")); ASSERT_EQUALS(true , MathLib::isInt("+1")); - ASSERT_EQUALS(true , MathLib::isInt("+1E+1")); - ASSERT_EQUALS(true , MathLib::isInt("+1E+10000")); - ASSERT_EQUALS(true , MathLib::isInt("-1E+1")); - ASSERT_EQUALS(true , MathLib::isInt("-1E+10000")); + ASSERT_EQUALS(false , MathLib::isInt("+1E+1")); + ASSERT_EQUALS(false , MathLib::isInt("+1E+10000")); + ASSERT_EQUALS(false , MathLib::isInt("-1E+1")); + ASSERT_EQUALS(false , MathLib::isInt("-1E+10000")); ASSERT_EQUALS(false, MathLib::isInt("-1E-1")); ASSERT_EQUALS(false, MathLib::isInt("-1E-10000")); @@ -310,6 +310,10 @@ private: ASSERT_EQUALS(false, MathLib::isInt("L")); ASSERT_EQUALS(false, MathLib::isInt("uL")); ASSERT_EQUALS(false, MathLib::isInt("LL")); + ASSERT_EQUALS(false, MathLib::isInt("e2")); + ASSERT_EQUALS(false, MathLib::isInt("E2")); + ASSERT_EQUALS(false, MathLib::isInt(".e2")); + ASSERT_EQUALS(false, MathLib::isInt(".E2")); } void isnegative() const { @@ -348,6 +352,13 @@ private: ASSERT_EQUALS(true , MathLib::isFloat("+0.")); ASSERT_EQUALS(true , MathLib::isFloat("-0.0")); ASSERT_EQUALS(true , MathLib::isFloat("+0.0")); + ASSERT_EQUALS(true , MathLib::isFloat("0E0")); + ASSERT_EQUALS(true , MathLib::isFloat("+0E0")); + ASSERT_EQUALS(true , MathLib::isFloat("+0E0")); + ASSERT_EQUALS(true , MathLib::isFloat("+0E+0")); + ASSERT_EQUALS(true , MathLib::isFloat("+0E-0")); + ASSERT_EQUALS(true , MathLib::isFloat("-0E+0")); + ASSERT_EQUALS(true , MathLib::isFloat("-0E-0")); ASSERT_EQUALS(true , MathLib::isFloat("+0.0E+1")); ASSERT_EQUALS(true , MathLib::isFloat("+0.0E-1")); ASSERT_EQUALS(true , MathLib::isFloat("-0.0E+1")); @@ -356,13 +367,20 @@ private: ASSERT_EQUALS(false , MathLib::isFloat("1")); ASSERT_EQUALS(false , MathLib::isFloat("-1")); ASSERT_EQUALS(false , MathLib::isFloat("+1")); - ASSERT_EQUALS(false , MathLib::isFloat("+1E+1")); - ASSERT_EQUALS(false , MathLib::isFloat("+1E+10000")); - ASSERT_EQUALS(false , MathLib::isFloat("-1E+1")); - ASSERT_EQUALS(false , MathLib::isFloat("-1E+10000")); + ASSERT_EQUALS(true , MathLib::isFloat("+1e+1")); + ASSERT_EQUALS(true , MathLib::isFloat("+1E+1")); + ASSERT_EQUALS(true , MathLib::isFloat("+1E+100")); + ASSERT_EQUALS(true , MathLib::isFloat("+1E+100f")); + ASSERT_EQUALS(true , MathLib::isFloat("+1E+001f")); + ASSERT_EQUALS(false , MathLib::isFloat("+1E+001f2")); + ASSERT_EQUALS(true , MathLib::isFloat("+1E+10000")); + ASSERT_EQUALS(true , MathLib::isFloat("-1E+1")); + ASSERT_EQUALS(true , MathLib::isFloat("-1E+10000")); ASSERT_EQUALS(true , MathLib::isFloat(".1250E+04")); ASSERT_EQUALS(true , MathLib::isFloat("-1E-1")); ASSERT_EQUALS(true , MathLib::isFloat("-1E-10000")); + ASSERT_EQUALS(true , MathLib::isFloat("+1.23e+01")); + ASSERT_EQUALS(true , MathLib::isFloat("+1.23E+01")); ASSERT_EQUALS(true , MathLib::isFloat("0.4")); ASSERT_EQUALS(true , MathLib::isFloat("2352.3f")); diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 4ecad6f02..3595cb011 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -8523,6 +8523,8 @@ private: ASSERT_EQUALS(false, Tokenizer::isZeroNumber("-1")); ASSERT_EQUALS(false, Tokenizer::isZeroNumber("")); ASSERT_EQUALS(false, Tokenizer::isZeroNumber("garbage")); + ASSERT_EQUALS(false, Tokenizer::isZeroNumber("E2")); + ASSERT_EQUALS(false, Tokenizer::isZeroNumber("2e")); } void isOneNumber() const {