improved `MathLib::to{ULong|Long|Double}Number()` and increased test coverage / added CMake option `USE_LIBCXX` / fixed #10695 (#4611)
This commit is contained in:
parent
89dba226dd
commit
8bb5ac0efd
|
@ -13,7 +13,7 @@ jobs:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
|
|
||||||
env:
|
env:
|
||||||
UBSAN_OPTIONS: print_stacktrace=1:halt_on_error=1
|
UBSAN_OPTIONS: print_stacktrace=1:halt_on_error=1:report_error_type=1
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
|
@ -13,11 +13,15 @@ if (MSVC)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# TODO: this should probably apply to the compiler and not the platform
|
# TODO: this should probably apply to the compiler and not the platform
|
||||||
if (CPPCHK_GLIBCXX_DEBUG AND UNIX)
|
if (CPPCHK_GLIBCXX_DEBUG AND UNIX AND CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
# TODO: check if this can be enabled again for Clang - also done in Makefile
|
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||||
if (CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
|
if (USE_LIBCXX)
|
||||||
|
add_definitions(-DLIBCXX_ENABLE_DEBUG_MODE)
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
# TODO: check if this can be enabled again for Clang - also done in Makefile
|
||||||
add_definitions(-D_GLIBCXX_DEBUG)
|
add_definitions(-D_GLIBCXX_DEBUG)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (HAVE_RULES)
|
if (HAVE_RULES)
|
||||||
|
|
|
@ -65,6 +65,11 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||||
add_compile_options(-gdwarf-4)
|
add_compile_options(-gdwarf-4)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (USE_LIBCXX)
|
||||||
|
add_compile_options(-stdlib=libc++)
|
||||||
|
add_link_options(-lc++)
|
||||||
|
endif()
|
||||||
|
|
||||||
add_compile_options_safe(-Wno-documentation-unknown-command)
|
add_compile_options_safe(-Wno-documentation-unknown-command)
|
||||||
|
|
||||||
# TODO: fix and enable these warnings - or move to suppression list below
|
# TODO: fix and enable these warnings - or move to suppression list below
|
||||||
|
|
|
@ -42,9 +42,10 @@ option(USE_QT6 "Prefer Qt6 when available"
|
||||||
|
|
||||||
option(HAVE_RULES "Usage of rules (needs PCRE library and headers)" OFF)
|
option(HAVE_RULES "Usage of rules (needs PCRE library and headers)" OFF)
|
||||||
option(USE_BUNDLED_TINYXML2 "Usage of bundled tinyxml2 library" ON)
|
option(USE_BUNDLED_TINYXML2 "Usage of bundled tinyxml2 library" ON)
|
||||||
option(CPPCHK_GLIBCXX_DEBUG "Usage of _GLIBCXX_DEBUG in Debug build" ON)
|
option(CPPCHK_GLIBCXX_DEBUG "Usage of STL debug checks in Debug build" ON)
|
||||||
option(USE_THREADS "Usage of threads instead of fork() for -j" OFF)
|
option(USE_THREADS "Usage of threads instead of fork() for -j" OFF)
|
||||||
option(USE_BOOST "Usage of Boost" OFF)
|
option(USE_BOOST "Usage of Boost" OFF)
|
||||||
|
option(USE_LIBCXX "Use libc++ instead of libstdc++" OFF)
|
||||||
|
|
||||||
option(DISABLE_CRTDBG_MAP_ALLOC "Disable usage of Visual Studio C++ memory leak detection in Debug build" OFF)
|
option(DISABLE_CRTDBG_MAP_ALLOC "Disable usage of Visual Studio C++ memory leak detection in Debug build" OFF)
|
||||||
option(NO_UNIX_SIGNAL_HANDLING "Disable usage of Unix Signal Handling" OFF)
|
option(NO_UNIX_SIGNAL_HANDLING "Disable usage of Unix Signal Handling" OFF)
|
||||||
|
|
|
@ -76,6 +76,7 @@ if (USE_BOOST)
|
||||||
message( STATUS "Boost_VERSION_STRING = ${Boost_VERSION_STRING}")
|
message( STATUS "Boost_VERSION_STRING = ${Boost_VERSION_STRING}")
|
||||||
message( STATUS "Boost_INCLUDE_DIRS = ${Boost_INCLUDE_DIRS}")
|
message( STATUS "Boost_INCLUDE_DIRS = ${Boost_INCLUDE_DIRS}")
|
||||||
endif()
|
endif()
|
||||||
|
message( STATUS "USE_LIBCXX = ${USE_LIBCXX}" )
|
||||||
message( STATUS )
|
message( STATUS )
|
||||||
|
|
||||||
if(${ANALYZE_ADDRESS})
|
if(${ANALYZE_ADDRESS})
|
||||||
|
|
|
@ -293,8 +293,10 @@ MathLib::biguint MathLib::toULongNumber(const std::string & str)
|
||||||
try {
|
try {
|
||||||
const biguint ret = std::stoull(str, nullptr, 16);
|
const biguint ret = std::stoull(str, nullptr, 16);
|
||||||
return ret;
|
return ret;
|
||||||
} catch (const std::out_of_range& e) {
|
} catch (const std::out_of_range& /*e*/) {
|
||||||
throw InternalError(nullptr, "Internal Error. MathLib::toULongNumber: out_of_range: " + str + " (" + e.what() +")");
|
throw InternalError(nullptr, "Internal Error. MathLib::toULongNumber: out_of_range: " + str);
|
||||||
|
} catch (const std::invalid_argument& /*e*/) {
|
||||||
|
throw InternalError(nullptr, "Internal Error. MathLib::toULongNumber: invalid_argument: " + str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,8 +305,10 @@ MathLib::biguint MathLib::toULongNumber(const std::string & str)
|
||||||
try {
|
try {
|
||||||
const biguint ret = std::stoull(str, nullptr, 8);
|
const biguint ret = std::stoull(str, nullptr, 8);
|
||||||
return ret;
|
return ret;
|
||||||
} catch (const std::out_of_range& e) {
|
} catch (const std::out_of_range& /*e*/) {
|
||||||
throw InternalError(nullptr, "Internal Error. MathLib::toULongNumber: out_of_range: " + str + " (" + e.what() +")");
|
throw InternalError(nullptr, "Internal Error. MathLib::toULongNumber: out_of_range: " + str);
|
||||||
|
} catch (const std::invalid_argument& /*e*/) {
|
||||||
|
throw InternalError(nullptr, "Internal Error. MathLib::toULongNumber: invalid_argument: " + str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,26 +322,38 @@ MathLib::biguint MathLib::toULongNumber(const std::string & str)
|
||||||
if (str[i] == '1')
|
if (str[i] == '1')
|
||||||
ret |= 1;
|
ret |= 1;
|
||||||
}
|
}
|
||||||
/* if (str[0] == '-')
|
if (str[0] == '-')
|
||||||
ret = -ret; */
|
ret = -ret;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isFloat(str)) {
|
if (isFloat(str)) {
|
||||||
// Things are going to be less precise now: the value can't b represented in the biguint type.
|
// Things are going to be less precise now: the value can't be represented in the biguint type.
|
||||||
// Use min/max values as an approximation. See #5843
|
// Use min/max values as an approximation. See #5843
|
||||||
const double doubleval = std::atof(str.c_str());
|
// TODO: bail out when we are out of range?
|
||||||
|
const double doubleval = toDoubleNumber(str);
|
||||||
if (doubleval > (double)std::numeric_limits<biguint>::max())
|
if (doubleval > (double)std::numeric_limits<biguint>::max())
|
||||||
return std::numeric_limits<biguint>::max();
|
return std::numeric_limits<biguint>::max();
|
||||||
else
|
else // cast to bigint to avoid UBSAN warning about negative double being out-of-range
|
||||||
return static_cast<biguint>(doubleval);
|
return static_cast<biguint>(static_cast<bigint>(doubleval));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isCharLiteral(str))
|
||||||
|
return simplecpp::characterLiteralToLL(str);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const biguint ret = std::stoull(str, nullptr, 10);
|
std::size_t idx = 0;
|
||||||
|
const biguint ret = std::stoull(str, &idx, 10);
|
||||||
|
if (idx != str.size()) {
|
||||||
|
const std::string s = str.substr(idx);
|
||||||
|
if (s.find_first_not_of("LlUu") != std::string::npos && s != "i64" && s != "ui64")
|
||||||
|
throw InternalError(nullptr, "Internal Error. MathLib::toULongNumber: input was not completely consumed: " + str);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
} catch (const std::out_of_range& e) {
|
} catch (const std::out_of_range& /*e*/) {
|
||||||
throw InternalError(nullptr, "Internal Error. MathLib::toULongNumber: out_of_range: " + str + " (" + e.what() +")");
|
throw InternalError(nullptr, "Internal Error. MathLib::toULongNumber: out_of_range: " + str);
|
||||||
|
} catch (const std::invalid_argument& /*e*/) {
|
||||||
|
throw InternalError(nullptr, "Internal Error. MathLib::toULongNumber: invalid_argument: " + str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,8 +371,10 @@ MathLib::bigint MathLib::toLongNumber(const std::string & str)
|
||||||
try {
|
try {
|
||||||
const biguint ret = std::stoull(str, nullptr, 16);
|
const biguint ret = std::stoull(str, nullptr, 16);
|
||||||
return (bigint)ret;
|
return (bigint)ret;
|
||||||
} catch (const std::out_of_range& e) {
|
} catch (const std::out_of_range& /*e*/) {
|
||||||
throw InternalError(nullptr, "Internal Error. MathLib::toLongNumber: out_of_range: " + str + " (" + e.what() +")");
|
throw InternalError(nullptr, "Internal Error. MathLib::toLongNumber: out_of_range: " + str);
|
||||||
|
} catch (const std::invalid_argument& /*e*/) {
|
||||||
|
throw InternalError(nullptr, "Internal Error. MathLib::toLongNumber: invalid_argument: " + str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,8 +383,10 @@ MathLib::bigint MathLib::toLongNumber(const std::string & str)
|
||||||
try {
|
try {
|
||||||
const biguint ret = std::stoull(str, nullptr, 8);
|
const biguint ret = std::stoull(str, nullptr, 8);
|
||||||
return ret;
|
return ret;
|
||||||
} catch (const std::out_of_range& e) {
|
} catch (const std::out_of_range& /*e*/) {
|
||||||
throw InternalError(nullptr, "Internal Error. MathLib::toLongNumber: out_of_range: " + str + " (" + e.what() +")");
|
throw InternalError(nullptr, "Internal Error. MathLib::toLongNumber: out_of_range: " + str);
|
||||||
|
} catch (const std::invalid_argument& /*e*/) {
|
||||||
|
throw InternalError(nullptr, "Internal Error. MathLib::toLongNumber: invalid_argument: " + str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -388,6 +408,7 @@ MathLib::bigint MathLib::toLongNumber(const std::string & str)
|
||||||
if (isFloat(str)) {
|
if (isFloat(str)) {
|
||||||
// Things are going to be less precise now: the value can't be represented in the bigint type.
|
// Things are going to be less precise now: the value can't be represented in the bigint type.
|
||||||
// Use min/max values as an approximation. See #5843
|
// Use min/max values as an approximation. See #5843
|
||||||
|
// TODO: bail out when we are out of range?
|
||||||
const double doubleval = toDoubleNumber(str);
|
const double doubleval = toDoubleNumber(str);
|
||||||
if (doubleval > (double)std::numeric_limits<bigint>::max())
|
if (doubleval > (double)std::numeric_limits<bigint>::max())
|
||||||
return std::numeric_limits<bigint>::max();
|
return std::numeric_limits<bigint>::max();
|
||||||
|
@ -401,10 +422,18 @@ MathLib::bigint MathLib::toLongNumber(const std::string & str)
|
||||||
return simplecpp::characterLiteralToLL(str);
|
return simplecpp::characterLiteralToLL(str);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const biguint ret = std::stoull(str, nullptr, 10);
|
std::size_t idx = 0;
|
||||||
|
const biguint ret = std::stoull(str, &idx, 10);
|
||||||
|
if (idx != str.size()) {
|
||||||
|
const std::string s = str.substr(idx);
|
||||||
|
if (s.find_first_not_of("LlUu") != std::string::npos && s != "i64" && s != "ui64")
|
||||||
|
throw InternalError(nullptr, "Internal Error. MathLib::toLongNumber: input was not completely consumed: " + str);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
} catch (const std::out_of_range& e) {
|
} catch (const std::out_of_range& /*e*/) {
|
||||||
throw InternalError(nullptr, "Internal Error. MathLib::toLongNumber: out_of_range: " + str + " (" + e.what() +")");
|
throw InternalError(nullptr, "Internal Error. MathLib::toLongNumber: out_of_range: " + str);
|
||||||
|
} catch (const std::invalid_argument& /*e*/) {
|
||||||
|
throw InternalError(nullptr, "Internal Error. MathLib::toLongNumber: invalid_argument: " + str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -463,7 +492,7 @@ double MathLib::toDoubleNumber(const std::string &str)
|
||||||
try {
|
try {
|
||||||
return simplecpp::characterLiteralToLL(str);
|
return simplecpp::characterLiteralToLL(str);
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
throw InternalError(nullptr, "Internal Error. MathLib::toLongNumber: characterLiteralToLL(" + str + ") => " + e.what());
|
throw InternalError(nullptr, "Internal Error. MathLib::toDoubleNumber: characterLiteralToLL(" + str + ") => " + e.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isIntHex(str))
|
if (isIntHex(str))
|
||||||
|
@ -479,7 +508,13 @@ double MathLib::toDoubleNumber(const std::string &str)
|
||||||
std::istringstream istr(str);
|
std::istringstream istr(str);
|
||||||
istr.imbue(std::locale::classic());
|
istr.imbue(std::locale::classic());
|
||||||
double ret;
|
double ret;
|
||||||
istr >> ret;
|
if (!(istr >> ret))
|
||||||
|
throw InternalError(nullptr, "Internal Error. MathLib::toDoubleNumber: conversion failed: " + str);
|
||||||
|
std::string s;
|
||||||
|
if (istr >> s) {
|
||||||
|
if (s.find_first_not_of("FfLl") != std::string::npos)
|
||||||
|
throw InternalError(nullptr, "Internal Error. MathLib::toDoubleNumber: input was not completely consumed: " + str);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,11 +523,12 @@ template<> std::string MathLib::toString<double>(double value)
|
||||||
std::ostringstream result;
|
std::ostringstream result;
|
||||||
result.precision(12);
|
result.precision(12);
|
||||||
result << value;
|
result << value;
|
||||||
if (result.str() == "-0")
|
std::string s = result.str();
|
||||||
|
if (s == "-0")
|
||||||
return "0.0";
|
return "0.0";
|
||||||
if (result.str().find('.') == std::string::npos)
|
if (s.find_first_of(".e") == std::string::npos)
|
||||||
return result.str() + ".0";
|
return s + ".0";
|
||||||
return result.str();
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MathLib::isFloat(const std::string &str)
|
bool MathLib::isFloat(const std::string &str)
|
||||||
|
|
|
@ -54,6 +54,7 @@ private:
|
||||||
TEST_CASE(calculate1);
|
TEST_CASE(calculate1);
|
||||||
TEST_CASE(typesuffix);
|
TEST_CASE(typesuffix);
|
||||||
TEST_CASE(toLongNumber);
|
TEST_CASE(toLongNumber);
|
||||||
|
TEST_CASE(toULongNumber);
|
||||||
TEST_CASE(toDoubleNumber);
|
TEST_CASE(toDoubleNumber);
|
||||||
TEST_CASE(naninf);
|
TEST_CASE(naninf);
|
||||||
TEST_CASE(isNullValue);
|
TEST_CASE(isNullValue);
|
||||||
|
@ -145,13 +146,13 @@ private:
|
||||||
ASSERT_EQUALS("5.0", MathLib::divide("25.5", "5.1"));
|
ASSERT_EQUALS("5.0", MathLib::divide("25.5", "5.1"));
|
||||||
ASSERT_EQUALS("7.0", MathLib::divide("21.", "3"));
|
ASSERT_EQUALS("7.0", MathLib::divide("21.", "3"));
|
||||||
ASSERT_EQUALS("1", MathLib::divide("3", "2"));
|
ASSERT_EQUALS("1", MathLib::divide("3", "2"));
|
||||||
ASSERT_THROW(MathLib::divide("123", "0"), InternalError); // decimal zero: throw
|
ASSERT_THROW_EQUALS(MathLib::divide("123", "0"), InternalError, "Internal Error: Division by zero"); // decimal zero: throw
|
||||||
ASSERT_THROW(MathLib::divide("123", "00"), InternalError); // octal zero: throw
|
ASSERT_THROW_EQUALS(MathLib::divide("123", "00"), InternalError, "Internal Error: Division by zero"); // octal zero: throw
|
||||||
ASSERT_THROW(MathLib::divide("123", "0x0"), InternalError); // hex zero: throw
|
ASSERT_THROW_EQUALS(MathLib::divide("123", "0x0"), InternalError, "Internal Error: Division by zero"); // hex zero: throw
|
||||||
MathLib::divide("123", "0.0f"); // float zero: don't throw
|
MathLib::divide("123", "0.0f"); // float zero: don't throw
|
||||||
MathLib::divide("123", "0.0"); // double zero: don't throw
|
MathLib::divide("123", "0.0"); // double zero: don't throw
|
||||||
MathLib::divide("123", "0.0L"); // long double zero: don't throw
|
MathLib::divide("123", "0.0L"); // long double zero: don't throw
|
||||||
ASSERT_THROW(MathLib::divide("-9223372036854775808", "-1"), InternalError); // #4520 - out of range => throw
|
ASSERT_THROW_EQUALS(MathLib::divide("-9223372036854775808", "-1"), InternalError, "Internal Error: Division overflow"); // #4520 - out of range => throw
|
||||||
ASSERT_EQUALS("4611686018427387904", MathLib::divide("-9223372036854775808", "-2")); // #6679
|
ASSERT_EQUALS("4611686018427387904", MathLib::divide("-9223372036854775808", "-2")); // #6679
|
||||||
|
|
||||||
|
|
||||||
|
@ -166,7 +167,7 @@ private:
|
||||||
ASSERT_EQUALS("1", MathLib::calculate("0", "1", '^'));
|
ASSERT_EQUALS("1", MathLib::calculate("0", "1", '^'));
|
||||||
|
|
||||||
// Unknown action should throw exception
|
// Unknown action should throw exception
|
||||||
ASSERT_THROW(MathLib::calculate("1","2",'j'),InternalError);
|
ASSERT_THROW_EQUALS(MathLib::calculate("1","2",'j'),InternalError, "Unexpected action 'j' in MathLib::calculate(). Please report this to Cppcheck developers.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void calculate1() const {
|
void calculate1() const {
|
||||||
|
@ -183,7 +184,7 @@ private:
|
||||||
MathLib::calculate("123", "0.0", '%'); // don't throw
|
MathLib::calculate("123", "0.0", '%'); // don't throw
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ASSERT_THROW(MathLib::calculate("123", "0", '%'), InternalError); // throw
|
ASSERT_THROW_EQUALS(MathLib::calculate("123", "0", '%'), InternalError, "Internal Error: Division by zero"); // throw
|
||||||
|
|
||||||
ASSERT_EQUALS("0", MathLib::calculate("1", "1", '^'));
|
ASSERT_EQUALS("0", MathLib::calculate("1", "1", '^'));
|
||||||
ASSERT_EQUALS("3", MathLib::calculate("2", "1", '^'));
|
ASSERT_EQUALS("3", MathLib::calculate("2", "1", '^'));
|
||||||
|
@ -250,6 +251,33 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void toLongNumber() const {
|
void toLongNumber() const {
|
||||||
|
// zero input
|
||||||
|
ASSERT_EQUALS(0, MathLib::toLongNumber("0"));
|
||||||
|
ASSERT_EQUALS(0, MathLib::toLongNumber("-0"));
|
||||||
|
ASSERT_EQUALS(0, MathLib::toLongNumber("+0"));
|
||||||
|
ASSERT_EQUALS(0, MathLib::toLongNumber("0L"));
|
||||||
|
ASSERT_EQUALS(0, MathLib::toLongNumber("0l"));
|
||||||
|
ASSERT_EQUALS(0, MathLib::toLongNumber("0LL"));
|
||||||
|
ASSERT_EQUALS(0, MathLib::toLongNumber("0ll"));
|
||||||
|
ASSERT_EQUALS(0, MathLib::toLongNumber("0U"));
|
||||||
|
ASSERT_EQUALS(0, MathLib::toLongNumber("0u"));
|
||||||
|
ASSERT_EQUALS(0, MathLib::toLongNumber("0UL"));
|
||||||
|
ASSERT_EQUALS(0, MathLib::toLongNumber("0ul"));
|
||||||
|
ASSERT_EQUALS(0, MathLib::toLongNumber("0ULL"));
|
||||||
|
ASSERT_EQUALS(0, MathLib::toLongNumber("0ull"));
|
||||||
|
ASSERT_EQUALS(0, MathLib::toLongNumber("0i64")); // Visual Studio-specific
|
||||||
|
ASSERT_EQUALS(0, MathLib::toLongNumber("0ui64")); // Visual Studio-specific
|
||||||
|
|
||||||
|
// TODO: needs to fail
|
||||||
|
//ASSERT_EQUALS(0, MathLib::toLongNumber("0lll"));
|
||||||
|
//ASSERT_EQUALS(0, MathLib::toLongNumber("0uu"));
|
||||||
|
|
||||||
|
ASSERT_EQUALS(1U, MathLib::toLongNumber("1U"));
|
||||||
|
ASSERT_EQUALS(10000U, MathLib::toLongNumber("1e4"));
|
||||||
|
ASSERT_EQUALS(10000U, MathLib::toLongNumber("1e4"));
|
||||||
|
ASSERT_EQUALS(0xFF00000000000000UL, MathLib::toLongNumber("0xFF00000000000000UL"));
|
||||||
|
ASSERT_EQUALS(0x0A00000000000000UL, MathLib::toLongNumber("0x0A00000000000000UL"));
|
||||||
|
|
||||||
// from hex
|
// from hex
|
||||||
ASSERT_EQUALS(0, MathLib::toLongNumber("0x0"));
|
ASSERT_EQUALS(0, MathLib::toLongNumber("0x0"));
|
||||||
ASSERT_EQUALS(0, MathLib::toLongNumber("-0x0"));
|
ASSERT_EQUALS(0, MathLib::toLongNumber("-0x0"));
|
||||||
|
@ -279,6 +307,8 @@ private:
|
||||||
ASSERT_EQUALS(1, MathLib::toLongNumber("0b1LLU"));
|
ASSERT_EQUALS(1, MathLib::toLongNumber("0b1LLU"));
|
||||||
ASSERT_EQUALS(1, MathLib::toLongNumber("+0b1"));
|
ASSERT_EQUALS(1, MathLib::toLongNumber("+0b1"));
|
||||||
ASSERT_EQUALS(-1, MathLib::toLongNumber("-0b1"));
|
ASSERT_EQUALS(-1, MathLib::toLongNumber("-0b1"));
|
||||||
|
ASSERT_EQUALS(9U, MathLib::toLongNumber("011"));
|
||||||
|
ASSERT_EQUALS(5U, MathLib::toLongNumber("0b101"));
|
||||||
ASSERT_EQUALS(215, MathLib::toLongNumber("0b11010111"));
|
ASSERT_EQUALS(215, MathLib::toLongNumber("0b11010111"));
|
||||||
ASSERT_EQUALS(-215, MathLib::toLongNumber("-0b11010111"));
|
ASSERT_EQUALS(-215, MathLib::toLongNumber("-0b11010111"));
|
||||||
ASSERT_EQUALS(215, MathLib::toLongNumber("0B11010111"));
|
ASSERT_EQUALS(215, MathLib::toLongNumber("0B11010111"));
|
||||||
|
@ -305,30 +335,6 @@ private:
|
||||||
|
|
||||||
ASSERT_EQUALS(-8552249625308161526, MathLib::toLongNumber("0x89504e470d0a1a0a"));
|
ASSERT_EQUALS(-8552249625308161526, MathLib::toLongNumber("0x89504e470d0a1a0a"));
|
||||||
ASSERT_EQUALS(-8481036456200365558, MathLib::toLongNumber("0x8a4d4e470d0a1a0a"));
|
ASSERT_EQUALS(-8481036456200365558, MathLib::toLongNumber("0x8a4d4e470d0a1a0a"));
|
||||||
ASSERT_EQUALS(9894494448401390090ULL, MathLib::toULongNumber("0x89504e470d0a1a0a"));
|
|
||||||
ASSERT_EQUALS(9965707617509186058ULL, MathLib::toULongNumber("0x8a4d4e470d0a1a0a"));
|
|
||||||
|
|
||||||
// zero input
|
|
||||||
ASSERT_EQUALS(0, MathLib::toULongNumber("0"));
|
|
||||||
ASSERT_EQUALS(0, MathLib::toULongNumber("-0"));
|
|
||||||
ASSERT_EQUALS(0, MathLib::toULongNumber("+0"));
|
|
||||||
ASSERT_EQUALS(0U, MathLib::toULongNumber("0U"));
|
|
||||||
ASSERT_EQUALS(0, MathLib::toULongNumber("-0x0"));
|
|
||||||
|
|
||||||
ASSERT_EQUALS(1U, MathLib::toULongNumber("1U"));
|
|
||||||
ASSERT_EQUALS(10000U, MathLib::toULongNumber("1e4"));
|
|
||||||
ASSERT_EQUALS(10000U, MathLib::toULongNumber("1e4"));
|
|
||||||
ASSERT_EQUALS(0xFF00000000000000UL, MathLib::toULongNumber("0xFF00000000000000UL"));
|
|
||||||
ASSERT_EQUALS(0x0A00000000000000UL, MathLib::toULongNumber("0x0A00000000000000UL"));
|
|
||||||
ASSERT_EQUALS(0, MathLib::toULongNumber("0b0"));
|
|
||||||
ASSERT_EQUALS(1, MathLib::toULongNumber("0b1"));
|
|
||||||
ASSERT_EQUALS(1, MathLib::toULongNumber("0b1U"));
|
|
||||||
ASSERT_EQUALS(1, MathLib::toULongNumber("0b1L"));
|
|
||||||
ASSERT_EQUALS(1, MathLib::toULongNumber("0b1LU"));
|
|
||||||
ASSERT_EQUALS(1, MathLib::toULongNumber("0b1LL"));
|
|
||||||
ASSERT_EQUALS(1, MathLib::toULongNumber("0b1LLU"));
|
|
||||||
ASSERT_EQUALS(9U, MathLib::toULongNumber("011"));
|
|
||||||
ASSERT_EQUALS(5U, MathLib::toULongNumber("0b101"));
|
|
||||||
|
|
||||||
// from long long
|
// from long long
|
||||||
/*
|
/*
|
||||||
|
@ -345,37 +351,20 @@ private:
|
||||||
ASSERT_EQUALS(std::numeric_limits<unsigned long long>::min(), MathLib::toLongNumber(std::to_string(std::numeric_limits<unsigned long long>::min())));
|
ASSERT_EQUALS(std::numeric_limits<unsigned long long>::min(), MathLib::toLongNumber(std::to_string(std::numeric_limits<unsigned long long>::min())));
|
||||||
ASSERT_EQUALS(std::numeric_limits<unsigned long long>::max(), MathLib::toLongNumber(std::to_string(std::numeric_limits<unsigned long long>::max())));
|
ASSERT_EQUALS(std::numeric_limits<unsigned long long>::max(), MathLib::toLongNumber(std::to_string(std::numeric_limits<unsigned long long>::max())));
|
||||||
|
|
||||||
ASSERT_EQUALS(std::numeric_limits<long long>::min(), MathLib::toULongNumber(std::to_string(std::numeric_limits<long long>::min())));
|
|
||||||
ASSERT_EQUALS(std::numeric_limits<long long>::max(), MathLib::toULongNumber(std::to_string(std::numeric_limits<long long>::max())));
|
|
||||||
ASSERT_EQUALS(std::numeric_limits<unsigned long long>::min(), MathLib::toULongNumber(std::to_string(std::numeric_limits<unsigned long long>::min())));
|
|
||||||
ASSERT_EQUALS(std::numeric_limits<unsigned long long>::max(), MathLib::toULongNumber(std::to_string(std::numeric_limits<unsigned long long>::max())));
|
|
||||||
|
|
||||||
// min/max and out-of-bounds - hex
|
// min/max and out-of-bounds - hex
|
||||||
{
|
{
|
||||||
const MathLib::bigint i = 0xFFFFFFFFFFFFFFFF;
|
const MathLib::bigint i = 0xFFFFFFFFFFFFFFFF;
|
||||||
ASSERT_EQUALS(i, MathLib::toLongNumber(std::to_string(i)));
|
ASSERT_EQUALS(i, MathLib::toLongNumber(std::to_string(i)));
|
||||||
ASSERT_EQUALS(i, MathLib::toLongNumber("0xFFFFFFFFFFFFFFFF"));
|
ASSERT_EQUALS(i, MathLib::toLongNumber("0xFFFFFFFFFFFFFFFF"));
|
||||||
}
|
}
|
||||||
{
|
|
||||||
const MathLib::biguint u = 0xFFFFFFFFFFFFFFFF;
|
|
||||||
ASSERT_EQUALS(u, MathLib::toULongNumber(std::to_string(u)));
|
|
||||||
ASSERT_EQUALS(u, MathLib::toULongNumber("0xFFFFFFFFFFFFFFFF"));
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
const MathLib::bigint i = -0xFFFFFFFFFFFFFFFF;
|
const MathLib::bigint i = -0xFFFFFFFFFFFFFFFF;
|
||||||
ASSERT_EQUALS(i, MathLib::toLongNumber(std::to_string(i)));
|
ASSERT_EQUALS(i, MathLib::toLongNumber(std::to_string(i)));
|
||||||
ASSERT_EQUALS(i, MathLib::toLongNumber("-0xFFFFFFFFFFFFFFFF"));
|
ASSERT_EQUALS(i, MathLib::toLongNumber("-0xFFFFFFFFFFFFFFFF"));
|
||||||
}
|
}
|
||||||
{
|
|
||||||
const MathLib::biguint u = -0xFFFFFFFFFFFFFFFF;
|
|
||||||
ASSERT_EQUALS(u, MathLib::toULongNumber(std::to_string(u)));
|
|
||||||
ASSERT_EQUALS(u, MathLib::toULongNumber("-0xFFFFFFFFFFFFFFFF"));
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT_THROW(MathLib::toLongNumber("0x10000000000000000"), InternalError);
|
ASSERT_THROW_EQUALS(MathLib::toLongNumber("0x10000000000000000"), InternalError, "Internal Error. MathLib::toLongNumber: out_of_range: 0x10000000000000000");
|
||||||
ASSERT_THROW(MathLib::toULongNumber("0x10000000000000000"), InternalError);
|
ASSERT_THROW_EQUALS(MathLib::toLongNumber("-0x10000000000000000"), InternalError, "Internal Error. MathLib::toLongNumber: out_of_range: -0x10000000000000000");
|
||||||
ASSERT_THROW(MathLib::toLongNumber("-0x10000000000000000"), InternalError);
|
|
||||||
ASSERT_THROW(MathLib::toULongNumber("-0x10000000000000000"), InternalError);
|
|
||||||
|
|
||||||
// min/max and out-of-bounds - octal
|
// min/max and out-of-bounds - octal
|
||||||
{
|
{
|
||||||
|
@ -383,26 +372,14 @@ private:
|
||||||
ASSERT_EQUALS(i, MathLib::toLongNumber(std::to_string(i)));
|
ASSERT_EQUALS(i, MathLib::toLongNumber(std::to_string(i)));
|
||||||
ASSERT_EQUALS(i, MathLib::toLongNumber("01777777777777777777777"));
|
ASSERT_EQUALS(i, MathLib::toLongNumber("01777777777777777777777"));
|
||||||
}
|
}
|
||||||
{
|
|
||||||
const MathLib::biguint u = 01777777777777777777777;
|
|
||||||
ASSERT_EQUALS(u, MathLib::toULongNumber(std::to_string(u)));
|
|
||||||
ASSERT_EQUALS(u, MathLib::toULongNumber("01777777777777777777777"));
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
const MathLib::bigint i = -01777777777777777777777;
|
const MathLib::bigint i = -01777777777777777777777;
|
||||||
ASSERT_EQUALS(i, MathLib::toLongNumber(std::to_string(i)));
|
ASSERT_EQUALS(i, MathLib::toLongNumber(std::to_string(i)));
|
||||||
ASSERT_EQUALS(i, MathLib::toLongNumber("-01777777777777777777777"));
|
ASSERT_EQUALS(i, MathLib::toLongNumber("-01777777777777777777777"));
|
||||||
}
|
}
|
||||||
{
|
|
||||||
const MathLib::biguint u = -01777777777777777777777;
|
|
||||||
ASSERT_EQUALS(u, MathLib::toULongNumber(std::to_string(u)));
|
|
||||||
ASSERT_EQUALS(u, MathLib::toULongNumber("-01777777777777777777777"));
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT_THROW(MathLib::toLongNumber("02000000000000000000000"), InternalError);
|
ASSERT_THROW_EQUALS(MathLib::toLongNumber("02000000000000000000000"), InternalError, "Internal Error. MathLib::toLongNumber: out_of_range: 02000000000000000000000");
|
||||||
ASSERT_THROW(MathLib::toULongNumber("02000000000000000000000"), InternalError);
|
ASSERT_THROW_EQUALS(MathLib::toLongNumber("-02000000000000000000000"), InternalError, "Internal Error. MathLib::toLongNumber: out_of_range: -02000000000000000000000");
|
||||||
ASSERT_THROW(MathLib::toLongNumber("-02000000000000000000000"), InternalError);
|
|
||||||
ASSERT_THROW(MathLib::toULongNumber("-02000000000000000000000"), InternalError);
|
|
||||||
|
|
||||||
// min/max and out-of-bounds - decimal
|
// min/max and out-of-bounds - decimal
|
||||||
{
|
{
|
||||||
|
@ -410,26 +387,176 @@ private:
|
||||||
ASSERT_EQUALS(i, MathLib::toLongNumber(std::to_string(i)));
|
ASSERT_EQUALS(i, MathLib::toLongNumber(std::to_string(i)));
|
||||||
ASSERT_EQUALS(i, MathLib::toLongNumber("18446744073709551615"));
|
ASSERT_EQUALS(i, MathLib::toLongNumber("18446744073709551615"));
|
||||||
}
|
}
|
||||||
{
|
|
||||||
const MathLib::biguint u = 18446744073709551615;
|
|
||||||
ASSERT_EQUALS(u, MathLib::toULongNumber(std::to_string(u)));
|
|
||||||
ASSERT_EQUALS(u, MathLib::toULongNumber("18446744073709551615"));
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
const MathLib::bigint i = -18446744073709551615;
|
const MathLib::bigint i = -18446744073709551615;
|
||||||
ASSERT_EQUALS(i, MathLib::toLongNumber(std::to_string(i)));
|
ASSERT_EQUALS(i, MathLib::toLongNumber(std::to_string(i)));
|
||||||
ASSERT_EQUALS(i, MathLib::toLongNumber("-18446744073709551615"));
|
ASSERT_EQUALS(i, MathLib::toLongNumber("-18446744073709551615"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ASSERT_THROW_EQUALS(MathLib::toLongNumber("18446744073709551616"), InternalError, "Internal Error. MathLib::toLongNumber: out_of_range: 18446744073709551616");
|
||||||
|
ASSERT_THROW_EQUALS(MathLib::toLongNumber("-18446744073709551616"), InternalError, "Internal Error. MathLib::toLongNumber: out_of_range: -18446744073709551616");
|
||||||
|
|
||||||
|
ASSERT_THROW_EQUALS(MathLib::toLongNumber("invalid"), InternalError, "Internal Error. MathLib::toLongNumber: invalid_argument: invalid");
|
||||||
|
|
||||||
|
ASSERT_THROW_EQUALS(MathLib::toLongNumber("1invalid"), InternalError, "Internal Error. MathLib::toLongNumber: input was not completely consumed: 1invalid");
|
||||||
|
ASSERT_THROW_EQUALS(MathLib::toLongNumber("1 invalid"), InternalError, "Internal Error. MathLib::toLongNumber: input was not completely consumed: 1 invalid");
|
||||||
|
|
||||||
|
// TODO: test binary
|
||||||
|
// TODO: test floating point
|
||||||
|
|
||||||
|
// TODO: test with 128-bit values
|
||||||
|
}
|
||||||
|
|
||||||
|
void toULongNumber() const {
|
||||||
|
// zero input
|
||||||
|
ASSERT_EQUALS(0, MathLib::toULongNumber("0"));
|
||||||
|
ASSERT_EQUALS(0, MathLib::toULongNumber("-0"));
|
||||||
|
ASSERT_EQUALS(0, MathLib::toULongNumber("+0"));
|
||||||
|
ASSERT_EQUALS(0, MathLib::toULongNumber("0L"));
|
||||||
|
ASSERT_EQUALS(0, MathLib::toULongNumber("0l"));
|
||||||
|
ASSERT_EQUALS(0, MathLib::toULongNumber("0LL"));
|
||||||
|
ASSERT_EQUALS(0, MathLib::toULongNumber("0ll"));
|
||||||
|
ASSERT_EQUALS(0, MathLib::toULongNumber("0U"));
|
||||||
|
ASSERT_EQUALS(0, MathLib::toULongNumber("0u"));
|
||||||
|
ASSERT_EQUALS(0, MathLib::toULongNumber("0UL"));
|
||||||
|
ASSERT_EQUALS(0, MathLib::toULongNumber("0ul"));
|
||||||
|
ASSERT_EQUALS(0, MathLib::toULongNumber("0ULL"));
|
||||||
|
ASSERT_EQUALS(0, MathLib::toULongNumber("0ull"));
|
||||||
|
ASSERT_EQUALS(0, MathLib::toULongNumber("0i64")); // Visual Studio-specific
|
||||||
|
ASSERT_EQUALS(0, MathLib::toULongNumber("0ui64")); // Visual Studio-specific
|
||||||
|
|
||||||
|
// TODO: needs to fail
|
||||||
|
//ASSERT_EQUALS(0, MathLib::toULongNumber("0lll"));
|
||||||
|
//ASSERT_EQUALS(0, MathLib::toULongNumber("0uu"));
|
||||||
|
|
||||||
|
ASSERT_EQUALS(1U, MathLib::toULongNumber("1U"));
|
||||||
|
ASSERT_EQUALS(10000U, MathLib::toULongNumber("1e4"));
|
||||||
|
ASSERT_EQUALS(10000U, MathLib::toULongNumber("1e4"));
|
||||||
|
ASSERT_EQUALS(0xFF00000000000000UL, MathLib::toULongNumber("0xFF00000000000000UL"));
|
||||||
|
ASSERT_EQUALS(0x0A00000000000000UL, MathLib::toULongNumber("0x0A00000000000000UL"));
|
||||||
|
|
||||||
|
// from hex
|
||||||
|
ASSERT_EQUALS(0, MathLib::toULongNumber("0x0"));
|
||||||
|
ASSERT_EQUALS(0, MathLib::toULongNumber("-0x0"));
|
||||||
|
ASSERT_EQUALS(0, MathLib::toULongNumber("+0x0"));
|
||||||
|
ASSERT_EQUALS(10, MathLib::toULongNumber("0xa"));
|
||||||
|
ASSERT_EQUALS(10995, MathLib::toULongNumber("0x2AF3"));
|
||||||
|
ASSERT_EQUALS(-10, MathLib::toULongNumber("-0xa"));
|
||||||
|
ASSERT_EQUALS(-10995, MathLib::toULongNumber("-0x2AF3"));
|
||||||
|
ASSERT_EQUALS(10, MathLib::toULongNumber("+0xa"));
|
||||||
|
ASSERT_EQUALS(10995, MathLib::toULongNumber("+0x2AF3"));
|
||||||
|
|
||||||
|
// from octal
|
||||||
|
ASSERT_EQUALS(8, MathLib::toULongNumber("010"));
|
||||||
|
ASSERT_EQUALS(8, MathLib::toULongNumber("+010"));
|
||||||
|
ASSERT_EQUALS(-8, MathLib::toULongNumber("-010"));
|
||||||
|
ASSERT_EQUALS(125, MathLib::toULongNumber("0175"));
|
||||||
|
ASSERT_EQUALS(125, MathLib::toULongNumber("+0175"));
|
||||||
|
ASSERT_EQUALS(-125, MathLib::toULongNumber("-0175"));
|
||||||
|
|
||||||
|
// from binary
|
||||||
|
ASSERT_EQUALS(0, MathLib::toULongNumber("0b0"));
|
||||||
|
ASSERT_EQUALS(1, MathLib::toULongNumber("0b1"));
|
||||||
|
ASSERT_EQUALS(1, MathLib::toULongNumber("0b1U"));
|
||||||
|
ASSERT_EQUALS(1, MathLib::toULongNumber("0b1L"));
|
||||||
|
ASSERT_EQUALS(1, MathLib::toULongNumber("0b1LU"));
|
||||||
|
ASSERT_EQUALS(1, MathLib::toULongNumber("0b1LL"));
|
||||||
|
ASSERT_EQUALS(1, MathLib::toULongNumber("0b1LLU"));
|
||||||
|
ASSERT_EQUALS(1, MathLib::toULongNumber("+0b1"));
|
||||||
|
ASSERT_EQUALS(-1, MathLib::toULongNumber("-0b1"));
|
||||||
|
ASSERT_EQUALS(9U, MathLib::toULongNumber("011"));
|
||||||
|
ASSERT_EQUALS(5U, MathLib::toULongNumber("0b101"));
|
||||||
|
ASSERT_EQUALS(215, MathLib::toULongNumber("0b11010111"));
|
||||||
|
ASSERT_EQUALS(-215, MathLib::toULongNumber("-0b11010111"));
|
||||||
|
ASSERT_EQUALS(215, MathLib::toULongNumber("0B11010111"));
|
||||||
|
|
||||||
|
// from base 10
|
||||||
|
ASSERT_EQUALS(10, MathLib::toULongNumber("10"));
|
||||||
|
ASSERT_EQUALS(10, MathLib::toULongNumber("10."));
|
||||||
|
ASSERT_EQUALS(10, MathLib::toULongNumber("10.0"));
|
||||||
|
ASSERT_EQUALS(100, MathLib::toULongNumber("10E+1"));
|
||||||
|
ASSERT_EQUALS(1, MathLib::toULongNumber("10E-1"));
|
||||||
|
ASSERT_EQUALS(100, MathLib::toULongNumber("+10E+1"));
|
||||||
|
ASSERT_EQUALS(-1, MathLib::toULongNumber("-10E-1"));
|
||||||
|
ASSERT_EQUALS(100, MathLib::toULongNumber("+10.E+1"));
|
||||||
|
ASSERT_EQUALS(-1, MathLib::toULongNumber("-10.E-1"));
|
||||||
|
ASSERT_EQUALS(100, MathLib::toULongNumber("+10.0E+1"));
|
||||||
|
ASSERT_EQUALS(-1, MathLib::toULongNumber("-10.0E-1"));
|
||||||
|
|
||||||
|
// from char
|
||||||
|
ASSERT_EQUALS((int)('A'), MathLib::toULongNumber("'A'"));
|
||||||
|
ASSERT_EQUALS((int)('\x10'), MathLib::toULongNumber("'\\x10'"));
|
||||||
|
ASSERT_EQUALS((int)('\100'), MathLib::toULongNumber("'\\100'"));
|
||||||
|
ASSERT_EQUALS((int)('\200'), MathLib::toULongNumber("'\\200'"));
|
||||||
|
ASSERT_EQUALS((int)(L'A'), MathLib::toULongNumber("L'A'"));
|
||||||
|
|
||||||
|
ASSERT_EQUALS(9894494448401390090ULL, MathLib::toULongNumber("0x89504e470d0a1a0a"));
|
||||||
|
ASSERT_EQUALS(9965707617509186058ULL, MathLib::toULongNumber("0x8a4d4e470d0a1a0a"));
|
||||||
|
|
||||||
|
// from long long
|
||||||
|
/*
|
||||||
|
* ASSERT_EQUALS(0xFF00000000000000LL, MathLib::toULongNumber("0xFF00000000000000LL"));
|
||||||
|
* This does not work in a portable way!
|
||||||
|
* While it succeeds on 32bit Visual Studio it fails on Linux 64bit because it is greater than 0x7FFFFFFFFFFFFFFF (=LLONG_MAX)
|
||||||
|
*/
|
||||||
|
|
||||||
|
ASSERT_EQUALS(0x0A00000000000000LL, MathLib::toULongNumber("0x0A00000000000000LL"));
|
||||||
|
|
||||||
|
// min/max numeric limits
|
||||||
|
ASSERT_EQUALS(std::numeric_limits<long long>::min(), MathLib::toULongNumber(std::to_string(std::numeric_limits<long long>::min())));
|
||||||
|
ASSERT_EQUALS(std::numeric_limits<long long>::max(), MathLib::toULongNumber(std::to_string(std::numeric_limits<long long>::max())));
|
||||||
|
ASSERT_EQUALS(std::numeric_limits<unsigned long long>::min(), MathLib::toULongNumber(std::to_string(std::numeric_limits<unsigned long long>::min())));
|
||||||
|
ASSERT_EQUALS(std::numeric_limits<unsigned long long>::max(), MathLib::toULongNumber(std::to_string(std::numeric_limits<unsigned long long>::max())));
|
||||||
|
|
||||||
|
// min/max and out-of-bounds - hex
|
||||||
|
{
|
||||||
|
const MathLib::biguint u = 0xFFFFFFFFFFFFFFFF;
|
||||||
|
ASSERT_EQUALS(u, MathLib::toULongNumber(std::to_string(u)));
|
||||||
|
ASSERT_EQUALS(u, MathLib::toULongNumber("0xFFFFFFFFFFFFFFFF"));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const MathLib::biguint u = -0xFFFFFFFFFFFFFFFF;
|
||||||
|
ASSERT_EQUALS(u, MathLib::toULongNumber(std::to_string(u)));
|
||||||
|
ASSERT_EQUALS(u, MathLib::toULongNumber("-0xFFFFFFFFFFFFFFFF"));
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT_THROW_EQUALS(MathLib::toULongNumber("0x10000000000000000"), InternalError, "Internal Error. MathLib::toULongNumber: out_of_range: 0x10000000000000000");
|
||||||
|
ASSERT_THROW_EQUALS(MathLib::toULongNumber("-0x10000000000000000"), InternalError, "Internal Error. MathLib::toULongNumber: out_of_range: -0x10000000000000000");
|
||||||
|
|
||||||
|
// min/max and out-of-bounds - octal
|
||||||
|
{
|
||||||
|
const MathLib::biguint u = 01777777777777777777777;
|
||||||
|
ASSERT_EQUALS(u, MathLib::toULongNumber(std::to_string(u)));
|
||||||
|
ASSERT_EQUALS(u, MathLib::toULongNumber("01777777777777777777777"));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const MathLib::biguint u = -01777777777777777777777;
|
||||||
|
ASSERT_EQUALS(u, MathLib::toULongNumber(std::to_string(u)));
|
||||||
|
ASSERT_EQUALS(u, MathLib::toULongNumber("-01777777777777777777777"));
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT_THROW_EQUALS(MathLib::toULongNumber("02000000000000000000000"), InternalError, "Internal Error. MathLib::toULongNumber: out_of_range: 02000000000000000000000");
|
||||||
|
ASSERT_THROW_EQUALS(MathLib::toULongNumber("-02000000000000000000000"), InternalError, "Internal Error. MathLib::toULongNumber: out_of_range: -02000000000000000000000");
|
||||||
|
|
||||||
|
// min/max and out-of-bounds - decimal
|
||||||
|
{
|
||||||
|
const MathLib::biguint u = 18446744073709551615;
|
||||||
|
ASSERT_EQUALS(u, MathLib::toULongNumber(std::to_string(u)));
|
||||||
|
ASSERT_EQUALS(u, MathLib::toULongNumber("18446744073709551615"));
|
||||||
|
}
|
||||||
{
|
{
|
||||||
const MathLib::biguint u = -18446744073709551615;
|
const MathLib::biguint u = -18446744073709551615;
|
||||||
ASSERT_EQUALS(u, MathLib::toULongNumber(std::to_string(u)));
|
ASSERT_EQUALS(u, MathLib::toULongNumber(std::to_string(u)));
|
||||||
ASSERT_EQUALS(u, MathLib::toULongNumber("-18446744073709551615"));
|
ASSERT_EQUALS(u, MathLib::toULongNumber("-18446744073709551615"));
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT_THROW(MathLib::toLongNumber("18446744073709551616"), InternalError);
|
ASSERT_THROW_EQUALS(MathLib::toULongNumber("18446744073709551616"), InternalError, "Internal Error. MathLib::toULongNumber: out_of_range: 18446744073709551616");
|
||||||
ASSERT_THROW(MathLib::toULongNumber("18446744073709551616"), InternalError);
|
ASSERT_THROW_EQUALS(MathLib::toULongNumber("-18446744073709551616"), InternalError, "Internal Error. MathLib::toULongNumber: out_of_range: -18446744073709551616");
|
||||||
ASSERT_THROW(MathLib::toLongNumber("-18446744073709551616"), InternalError);
|
|
||||||
ASSERT_THROW(MathLib::toULongNumber("-18446744073709551616"), InternalError);
|
ASSERT_THROW_EQUALS(MathLib::toULongNumber("invalid"), InternalError, "Internal Error. MathLib::toULongNumber: invalid_argument: invalid");
|
||||||
|
|
||||||
|
ASSERT_THROW_EQUALS(MathLib::toULongNumber("1invalid"), InternalError, "Internal Error. MathLib::toULongNumber: input was not completely consumed: 1invalid");
|
||||||
|
ASSERT_THROW_EQUALS(MathLib::toULongNumber("1 invalid"), InternalError, "Internal Error. MathLib::toULongNumber: input was not completely consumed: 1 invalid");
|
||||||
|
|
||||||
// TODO: test binary
|
// TODO: test binary
|
||||||
// TODO: test floating point
|
// TODO: test floating point
|
||||||
|
@ -438,10 +565,22 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void toDoubleNumber() const {
|
void toDoubleNumber() const {
|
||||||
ASSERT_EQUALS_DOUBLE(1.0, MathLib::toDoubleNumber("1"), 0.001);
|
// float values
|
||||||
|
ASSERT_EQUALS_DOUBLE(1.0, MathLib::toDoubleNumber("1."), 0.001);
|
||||||
|
ASSERT_EQUALS_DOUBLE(1.0, MathLib::toDoubleNumber("1.f"), 0.001);
|
||||||
|
ASSERT_EQUALS_DOUBLE(1.0, MathLib::toDoubleNumber("1.F"), 0.001);
|
||||||
|
ASSERT_EQUALS_DOUBLE(1.0, MathLib::toDoubleNumber("1.l"), 0.001);
|
||||||
|
ASSERT_EQUALS_DOUBLE(1.0, MathLib::toDoubleNumber("1.L"), 0.001);
|
||||||
|
ASSERT_EQUALS_DOUBLE(1.0, MathLib::toDoubleNumber("1.0"), 0.001);
|
||||||
|
ASSERT_EQUALS_DOUBLE(1.0, MathLib::toDoubleNumber("1.0f"), 0.001);
|
||||||
|
ASSERT_EQUALS_DOUBLE(1.0, MathLib::toDoubleNumber("1.0F"), 0.001);
|
||||||
|
ASSERT_EQUALS_DOUBLE(1.0, MathLib::toDoubleNumber("1.0l"), 0.001);
|
||||||
|
ASSERT_EQUALS_DOUBLE(1.0, MathLib::toDoubleNumber("1.0L"), 0.001);
|
||||||
ASSERT_EQUALS_DOUBLE(1.0, MathLib::toDoubleNumber("0x1"), 0.001);
|
ASSERT_EQUALS_DOUBLE(1.0, MathLib::toDoubleNumber("0x1"), 0.001);
|
||||||
ASSERT_EQUALS_DOUBLE(10.0, MathLib::toDoubleNumber("10"), 0.001);
|
ASSERT_EQUALS_DOUBLE(10.0, MathLib::toDoubleNumber("10"), 0.001);
|
||||||
ASSERT_EQUALS_DOUBLE(1000.0, MathLib::toDoubleNumber("10E+2"), 0.001);
|
ASSERT_EQUALS_DOUBLE(1000.0, MathLib::toDoubleNumber("10E+2"), 0.001);
|
||||||
|
ASSERT_EQUALS_DOUBLE(1000.0, MathLib::toDoubleNumber("10E+2l"), 0.001);
|
||||||
|
ASSERT_EQUALS_DOUBLE(1000.0, MathLib::toDoubleNumber("10E+2L"), 0.001);
|
||||||
ASSERT_EQUALS_DOUBLE(100.0, MathLib::toDoubleNumber("1.0E+2"), 0.001);
|
ASSERT_EQUALS_DOUBLE(100.0, MathLib::toDoubleNumber("1.0E+2"), 0.001);
|
||||||
ASSERT_EQUALS_DOUBLE(-100.0, MathLib::toDoubleNumber("-1.0E+2"), 0.001);
|
ASSERT_EQUALS_DOUBLE(-100.0, MathLib::toDoubleNumber("-1.0E+2"), 0.001);
|
||||||
ASSERT_EQUALS_DOUBLE(-1e+10, MathLib::toDoubleNumber("-1.0E+10"), 1);
|
ASSERT_EQUALS_DOUBLE(-1e+10, MathLib::toDoubleNumber("-1.0E+10"), 1);
|
||||||
|
@ -449,6 +588,34 @@ private:
|
||||||
ASSERT_EQUALS_DOUBLE(1e+10, MathLib::toDoubleNumber("+1.0E+10"), 1);
|
ASSERT_EQUALS_DOUBLE(1e+10, MathLib::toDoubleNumber("+1.0E+10"), 1);
|
||||||
ASSERT_EQUALS_DOUBLE(100.0, MathLib::toDoubleNumber("1.0E+2"), 0.001);
|
ASSERT_EQUALS_DOUBLE(100.0, MathLib::toDoubleNumber("1.0E+2"), 0.001);
|
||||||
ASSERT_EQUALS_DOUBLE(1e+10, MathLib::toDoubleNumber("1.0E+10"), 1);
|
ASSERT_EQUALS_DOUBLE(1e+10, MathLib::toDoubleNumber("1.0E+10"), 1);
|
||||||
|
|
||||||
|
// valid non-float values
|
||||||
|
ASSERT_EQUALS_DOUBLE(1.0, MathLib::toDoubleNumber("1"), 0.001);
|
||||||
|
ASSERT_EQUALS_DOUBLE(1.0, MathLib::toDoubleNumber("1l"), 0.001);
|
||||||
|
ASSERT_EQUALS_DOUBLE(1.0, MathLib::toDoubleNumber("1L"), 0.001);
|
||||||
|
ASSERT_EQUALS_DOUBLE(1.0, MathLib::toDoubleNumber("1ll"), 0.001);
|
||||||
|
ASSERT_EQUALS_DOUBLE(1.0, MathLib::toDoubleNumber("1LL"), 0.001);
|
||||||
|
// TODO: need to succeed
|
||||||
|
//ASSERT_EQUALS_DOUBLE(1.0, MathLib::toDoubleNumber("1u"), 0.001);
|
||||||
|
//ASSERT_EQUALS_DOUBLE(1.0, MathLib::toDoubleNumber("1U"), 0.001);
|
||||||
|
//ASSERT_EQUALS_DOUBLE(1.0, MathLib::toDoubleNumber("1ul"), 0.001);
|
||||||
|
//ASSERT_EQUALS_DOUBLE(1.0, MathLib::toDoubleNumber("1UL"), 0.001);
|
||||||
|
//ASSERT_EQUALS_DOUBLE(1.0, MathLib::toDoubleNumber("1ULL"), 0.001);
|
||||||
|
//ASSERT_EQUALS_DOUBLE(1.0, MathLib::toDoubleNumber("1ULL"), 0.001);
|
||||||
|
|
||||||
|
// TODO: need to fail
|
||||||
|
// invalid values
|
||||||
|
//ASSERT_EQUALS_DOUBLE(1.0, MathLib::toDoubleNumber("1f"), 0.001);
|
||||||
|
//ASSERT_EQUALS_DOUBLE(1.0, MathLib::toDoubleNumber("1F"), 0.001);
|
||||||
|
//ASSERT_EQUALS_DOUBLE(1.0, MathLib::toDoubleNumber("1.ff"), 0.001);
|
||||||
|
//ASSERT_EQUALS_DOUBLE(1.0, MathLib::toDoubleNumber("1.FF"), 0.001);
|
||||||
|
//ASSERT_EQUALS_DOUBLE(1.0, MathLib::toDoubleNumber("1.ll"), 0.001);
|
||||||
|
//ASSERT_EQUALS_DOUBLE(1.0, MathLib::toDoubleNumber("1.0LL"), 0.001);
|
||||||
|
//ASSERT_EQUALS_DOUBLE(1.0, MathLib::toDoubleNumber("1.0ff"), 0.001);
|
||||||
|
//ASSERT_EQUALS_DOUBLE(1.0, MathLib::toDoubleNumber("1.0FF"), 0.001);
|
||||||
|
//ASSERT_EQUALS_DOUBLE(1.0, MathLib::toDoubleNumber("1.0ll"), 0.001);
|
||||||
|
//ASSERT_EQUALS_DOUBLE(1.0, MathLib::toDoubleNumber("1.0LL"), 0.001);
|
||||||
|
|
||||||
ASSERT_EQUALS_DOUBLE(0.0, MathLib::toDoubleNumber("0E+0"), 0.000001);
|
ASSERT_EQUALS_DOUBLE(0.0, MathLib::toDoubleNumber("0E+0"), 0.000001);
|
||||||
ASSERT_EQUALS_DOUBLE(0.0, MathLib::toDoubleNumber("0E-0"), 0.000001);
|
ASSERT_EQUALS_DOUBLE(0.0, MathLib::toDoubleNumber("0E-0"), 0.000001);
|
||||||
ASSERT_EQUALS_DOUBLE(0.0, MathLib::toDoubleNumber("0E+00"), 0.000001);
|
ASSERT_EQUALS_DOUBLE(0.0, MathLib::toDoubleNumber("0E+00"), 0.000001);
|
||||||
|
@ -476,6 +643,25 @@ private:
|
||||||
ASSERT_EQUALS_DOUBLE(9.0, MathLib::toDoubleNumber("0x1.2P3"), 0.000001);
|
ASSERT_EQUALS_DOUBLE(9.0, MathLib::toDoubleNumber("0x1.2P3"), 0.000001);
|
||||||
ASSERT_EQUALS_DOUBLE(0.0625, MathLib::toDoubleNumber("0x.1P0"), 0.000001);
|
ASSERT_EQUALS_DOUBLE(0.0625, MathLib::toDoubleNumber("0x.1P0"), 0.000001);
|
||||||
|
|
||||||
|
// from char
|
||||||
|
ASSERT_EQUALS_DOUBLE((double)('A'), MathLib::toDoubleNumber("'A'"), 0.000001);
|
||||||
|
ASSERT_EQUALS_DOUBLE((double)('\x10'), MathLib::toDoubleNumber("'\\x10'"), 0.000001);
|
||||||
|
ASSERT_EQUALS_DOUBLE((double)('\100'), MathLib::toDoubleNumber("'\\100'"), 0.000001);
|
||||||
|
ASSERT_EQUALS_DOUBLE((double)('\200'), MathLib::toDoubleNumber("'\\200'"), 0.000001);
|
||||||
|
ASSERT_EQUALS_DOUBLE((double)(L'A'), MathLib::toDoubleNumber("L'A'"), 0.000001);
|
||||||
|
|
||||||
|
ASSERT_THROW_EQUALS(MathLib::toDoubleNumber("invalid"), InternalError, "Internal Error. MathLib::toDoubleNumber: conversion failed: invalid");
|
||||||
|
|
||||||
|
#ifdef _LIBCPP_VERSION
|
||||||
|
ASSERT_THROW_EQUALS(MathLib::toDoubleNumber("1invalid"), InternalError, "Internal Error. MathLib::toDoubleNumber: conversion failed: 1invalid");
|
||||||
|
ASSERT_THROW_EQUALS(MathLib::toDoubleNumber("1.1invalid"), InternalError, "Internal Error. MathLib::toDoubleNumber: conversion failed: 1.1invalid");
|
||||||
|
#else
|
||||||
|
ASSERT_THROW_EQUALS(MathLib::toDoubleNumber("1invalid"), InternalError, "Internal Error. MathLib::toDoubleNumber: input was not completely consumed: 1invalid");
|
||||||
|
ASSERT_THROW_EQUALS(MathLib::toDoubleNumber("1.1invalid"), InternalError, "Internal Error. MathLib::toDoubleNumber: input was not completely consumed: 1.1invalid");
|
||||||
|
#endif
|
||||||
|
ASSERT_THROW_EQUALS(MathLib::toDoubleNumber("1 invalid"), InternalError, "Internal Error. MathLib::toDoubleNumber: input was not completely consumed: 1 invalid");
|
||||||
|
ASSERT_THROW_EQUALS(MathLib::toDoubleNumber("-1e-08.0"), InternalError, "Internal Error. MathLib::toDoubleNumber: input was not completely consumed: -1e-08.0");
|
||||||
|
|
||||||
// verify: string --> double --> string conversion
|
// verify: string --> double --> string conversion
|
||||||
ASSERT_EQUALS("1.0", MathLib::toString(MathLib::toDoubleNumber("1.0f")));
|
ASSERT_EQUALS("1.0", MathLib::toString(MathLib::toDoubleNumber("1.0f")));
|
||||||
ASSERT_EQUALS("1.0", MathLib::toString(MathLib::toDoubleNumber("1.0")));
|
ASSERT_EQUALS("1.0", MathLib::toString(MathLib::toDoubleNumber("1.0")));
|
||||||
|
@ -1230,6 +1416,9 @@ private:
|
||||||
ASSERT_EQUALS("0.000000", MathLib::toString(0.0L));
|
ASSERT_EQUALS("0.000000", MathLib::toString(0.0L));
|
||||||
ASSERT_EQUALS("0.000000", MathLib::toString(+0.0L));
|
ASSERT_EQUALS("0.000000", MathLib::toString(+0.0L));
|
||||||
ASSERT_EQUALS("-0.000000", MathLib::toString(-0.0L));
|
ASSERT_EQUALS("-0.000000", MathLib::toString(-0.0L));
|
||||||
|
|
||||||
|
ASSERT_EQUALS("1e-08", MathLib::toString(0.00000001));
|
||||||
|
ASSERT_EQUALS("-1e-08", MathLib::toString(-0.00000001));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPP14DigitSeparators() const { // Ticket #7137, #7565
|
void CPP14DigitSeparators() const { // Ticket #7137, #7565
|
||||||
|
|
Loading…
Reference in New Issue