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:
parent
9788333ee9
commit
c391a03db6
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue