added acos() check to ticket #1513; added testcases for MathLib::toDoubleNumber(), now double conversion of zeros is handled correctly; changed assertEquals() function of testsuite parameters from unsigned int to double. This is needed to avoid overflow of unsigned int by comparing negative floating point values.

This commit is contained in:
Martin Ettl 2010-04-02 20:23:37 +02:00
parent 9788333ee9
commit c391a03db6
6 changed files with 75 additions and 4 deletions

View File

@ -30,6 +30,7 @@
#include <cstring> #include <cstring>
#include <cctype> #include <cctype>
#include <memory> #include <memory>
#include <cmath> // fabs()
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Register this check class (by creating a static instance of it) // Register this check class (by creating a static instance of it)
@ -2472,6 +2473,12 @@ void CheckOther::checkMathFunctions()
MathLib::toLongNumber(tok->tokAt(2)->str()) <= 0) MathLib::toLongNumber(tok->tokAt(2)->str()) <= 0)
{ {
mathfunctionCallError(tok); mathfunctionCallError(tok);
}
// acos( x ) x is defined for intervall [-1,+1], but not beyound
else if(Token::Match(tok, "acos ( %num% )") &&
fabs(MathLib::toDoubleNumber(tok->tokAt(2)->str())) > 1.0)
{
mathfunctionCallError(tok);
} }
} }
} }

View File

@ -55,6 +55,11 @@ double MathLib::toDoubleNumber(const std::string &str)
{ {
return std::strtoul(str.c_str(), '\0', 16); return std::strtoul(str.c_str(), '\0', 16);
} }
// nullcheck
else if (str == "-0" || str == "-0.0" || str == "-0."
|| str == "+0" || str == "+0.0" || str == "+0.")
return 0.0;
// otherwise, convert to double
std::istringstream istr(str.c_str()); std::istringstream istr(str.c_str());
double ret; double ret;
istr >> ret; istr >> ret;

View File

@ -115,6 +115,27 @@ private:
ASSERT_EQUALS(-1 , MathLib::toLongNumber("-10.E-1")); ASSERT_EQUALS(-1 , MathLib::toLongNumber("-10.E-1"));
ASSERT_EQUALS(100 , MathLib::toLongNumber("+10.0E+1")); ASSERT_EQUALS(100 , MathLib::toLongNumber("+10.0E+1"));
ASSERT_EQUALS(-1 , MathLib::toLongNumber("-10.0E-1")); ASSERT_EQUALS(-1 , MathLib::toLongNumber("-10.0E-1"));
// -----------------
// to double number:
// -----------------
ASSERT_EQUALS(10.0 , MathLib::toDoubleNumber("10"));
ASSERT_EQUALS(1000.0, MathLib::toDoubleNumber("10E+2"));
ASSERT_EQUALS(100.0 , MathLib::toDoubleNumber("1.0E+2"));
ASSERT_EQUALS(-100.0, MathLib::toDoubleNumber("-1.0E+2"));
ASSERT_EQUALS(-1e+10, MathLib::toDoubleNumber("-1.0E+10"));
ASSERT_EQUALS(100.0 , MathLib::toDoubleNumber("+1.0E+2"));
ASSERT_EQUALS(1e+10 , MathLib::toDoubleNumber("+1.0E+10"));
ASSERT_EQUALS(100.0 , MathLib::toDoubleNumber("1.0E+2"));
ASSERT_EQUALS(1e+10 , MathLib::toDoubleNumber("1.0E+10"));
ASSERT_EQUALS(0.0 , MathLib::toDoubleNumber("0"));
ASSERT_EQUALS(0.0 , MathLib::toDoubleNumber("-0"));
ASSERT_EQUALS(0.0 , MathLib::toDoubleNumber("+0"));
ASSERT_EQUALS(0.0 , MathLib::toDoubleNumber("-0."));
ASSERT_EQUALS(0.0 , MathLib::toDoubleNumber("+0."));
ASSERT_EQUALS(0.0 , MathLib::toDoubleNumber("-0.0"));
ASSERT_EQUALS(0.0 , MathLib::toDoubleNumber("+0.0"));
} }
void isint() void isint()

View File

@ -2169,6 +2169,7 @@ private:
void mathfunctionCall1() void mathfunctionCall1()
{ {
// log|log10
check("void foo()\n" check("void foo()\n"
"{\n" "{\n"
" std::cout << log(-2) << std::endl;\n" " std::cout << log(-2) << std::endl;\n"
@ -2228,9 +2229,42 @@ private:
" std::cout << log(1E-3) << std::endl;\n" " std::cout << log(1E-3) << std::endl;\n"
"}"); "}");
TODO_ASSERT_EQUALS("", errout.str()); TODO_ASSERT_EQUALS("", errout.str());
// acos
check("void foo()\n"
"{\n"
" std::cout << acos(1) << std::endl;\n"
" std::cout << acos(-1) << std::endl;\n"
" std::cout << acos(0.1) << std::endl;\n"
" std::cout << acos(0.0001) << std::endl;\n"
" std::cout << acos(0.01) << std::endl;\n"
" std::cout << acos(1.0E-1) << std::endl;\n"
" std::cout << acos(-1.0E-1) << std::endl;\n"
" std::cout << acos(+1.0E-1) << std::endl;\n"
" std::cout << acos(0.1E-1) << std::endl;\n"
" std::cout << acos(+0.1E-1) << std::endl;\n"
" std::cout << acos(-0.1E-1) << std::endl;\n"
"}");
ASSERT_EQUALS("", errout.str());
check("void foo()\n"
"{\n"
" std::cout << acos(1.1) << std::endl;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (error) Passing value 1.1 to acos() leads to undefined result\n", errout.str());
check("void foo()\n"
"{\n"
" std::cout << acos(-1.1) << std::endl;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (error) Passing value -1.1 to acos() leads to undefined result\n", errout.str());
check("void foo()\n"
"{\n"
" std::cout << acos(-110) << std::endl;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (error) Passing value -110 to acos() leads to undefined result\n", errout.str());
} }
}; };
REGISTER_TEST(TestOther) REGISTER_TEST(TestOther)

View File

@ -118,7 +118,7 @@ void TestFixture::assertEquals(const char *filename, int linenr, const std::stri
} }
} }
void TestFixture::assertEquals(const char *filename, int linenr, unsigned int expected, unsigned int actual) void TestFixture::assertEquals(const char *filename, int linenr, double expected, double actual)
{ {
std::ostringstream ostr1; std::ostringstream ostr1;
ostr1 << expected; ostr1 << expected;

View File

@ -42,7 +42,11 @@ protected:
bool runTest(const char testname[]); bool runTest(const char testname[]);
void assertEquals(const char *filename, int linenr, const std::string &expected, const std::string &actual); void assertEquals(const char *filename, int linenr, const std::string &expected, const std::string &actual);
void assertEquals(const char *filename, int linenr, unsigned int expected, unsigned int actual);
// the vars expected and actual need to be of type double, in order to avoid overflow of unsigned int
// e.g: ASSERT_EQUALS(-100.0, MathLib::toDoubleNumber("-1.0E+2")); whould not work without this.
void assertEquals(const char *filename, int linenr, double expected, double actual);
void todoAssertEquals(const char *filename, int linenr, const std::string &expected, const std::string &actual); void todoAssertEquals(const char *filename, int linenr, const std::string &expected, const std::string &actual);
void todoAssertEquals(const char *filename, int linenr, unsigned int expected, unsigned int actual); void todoAssertEquals(const char *filename, int linenr, unsigned int expected, unsigned int actual);
void assertThrowFail(const char *filename, int linenr); void assertThrowFail(const char *filename, int linenr);