MathLib: renamed `to{U}LongNumber()` to `toBig{U}Number()` (#5503)

The name was misleading as it was actually a `long long` and also if we
ever move to an (optional) 128-bit value it wouldn't even less fitting.
We should name it to match our alias type.
This commit is contained in:
Oliver Stöneberg 2023-10-05 19:21:42 +02:00 committed by GitHub
parent fc700b68eb
commit fe8730cf0f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 298 additions and 284 deletions

View File

@ -106,7 +106,7 @@ void CheckCondition::assignIf()
if (Token::Match(tok->next(), "%num% [&|]")) { if (Token::Match(tok->next(), "%num% [&|]")) {
bitop = tok->strAt(2).at(0); bitop = tok->strAt(2).at(0);
num = MathLib::toLongNumber(tok->next()->str()); num = MathLib::toBigNumber(tok->next()->str());
} else { } else {
const Token *endToken = Token::findsimplematch(tok, ";"); const Token *endToken = Token::findsimplematch(tok, ";");
@ -116,7 +116,7 @@ void CheckCondition::assignIf()
if (endToken && Token::Match(endToken->tokAt(-2), "[&|] %num% ;")) { if (endToken && Token::Match(endToken->tokAt(-2), "[&|] %num% ;")) {
bitop = endToken->strAt(-2).at(0); bitop = endToken->strAt(-2).at(0);
num = MathLib::toLongNumber(endToken->previous()->str()); num = MathLib::toBigNumber(endToken->previous()->str());
} }
} }
@ -169,7 +169,7 @@ bool CheckCondition::assignIfParseScope(const Token * const assignTok,
for (const Token *tok2 = startTok; tok2; tok2 = tok2->next()) { for (const Token *tok2 = startTok; tok2; tok2 = tok2->next()) {
if ((bitop == '&') && Token::Match(tok2->tokAt(2), "%varid% %cop% %num% ;", varid) && tok2->strAt(3) == std::string(1U, bitop)) { if ((bitop == '&') && Token::Match(tok2->tokAt(2), "%varid% %cop% %num% ;", varid) && tok2->strAt(3) == std::string(1U, bitop)) {
const MathLib::bigint num2 = MathLib::toLongNumber(tok2->strAt(4)); const MathLib::bigint num2 = MathLib::toBigNumber(tok2->strAt(4));
if (0 == (num & num2)) if (0 == (num & num2))
mismatchingBitAndError(assignTok, num, tok2, num2); mismatchingBitAndError(assignTok, num, tok2, num2);
} }
@ -177,7 +177,7 @@ bool CheckCondition::assignIfParseScope(const Token * const assignTok,
return true; return true;
} }
if (bitop == '&' && Token::Match(tok2, "%varid% &= %num% ;", varid)) { if (bitop == '&' && Token::Match(tok2, "%varid% &= %num% ;", varid)) {
const MathLib::bigint num2 = MathLib::toLongNumber(tok2->strAt(2)); const MathLib::bigint num2 = MathLib::toBigNumber(tok2->strAt(2));
if (0 == (num & num2)) if (0 == (num & num2))
mismatchingBitAndError(assignTok, num, tok2, num2); mismatchingBitAndError(assignTok, num, tok2, num2);
} }
@ -212,7 +212,7 @@ bool CheckCondition::assignIfParseScope(const Token * const assignTok,
} }
if (Token::Match(tok2,"&&|%oror%|( %varid% ==|!= %num% &&|%oror%|)", varid)) { if (Token::Match(tok2,"&&|%oror%|( %varid% ==|!= %num% &&|%oror%|)", varid)) {
const Token *vartok = tok2->next(); const Token *vartok = tok2->next();
const MathLib::bigint num2 = MathLib::toLongNumber(vartok->strAt(2)); const MathLib::bigint num2 = MathLib::toBigNumber(vartok->strAt(2));
if ((num & num2) != ((bitop=='&') ? num2 : num)) { if ((num & num2) != ((bitop=='&') ? num2 : num)) {
const std::string& op(vartok->strAt(1)); const std::string& op(vartok->strAt(1));
const bool alwaysTrue = op == "!="; const bool alwaysTrue = op == "!=";
@ -266,11 +266,11 @@ void CheckCondition::mismatchingBitAndError(const Token *tok1, const MathLib::bi
static void getnumchildren(const Token *tok, std::list<MathLib::bigint> &numchildren) static void getnumchildren(const Token *tok, std::list<MathLib::bigint> &numchildren)
{ {
if (tok->astOperand1() && tok->astOperand1()->isNumber()) if (tok->astOperand1() && tok->astOperand1()->isNumber())
numchildren.push_back(MathLib::toLongNumber(tok->astOperand1()->str())); numchildren.push_back(MathLib::toBigNumber(tok->astOperand1()->str()));
else if (tok->astOperand1() && tok->str() == tok->astOperand1()->str()) else if (tok->astOperand1() && tok->str() == tok->astOperand1()->str())
getnumchildren(tok->astOperand1(), numchildren); getnumchildren(tok->astOperand1(), numchildren);
if (tok->astOperand2() && tok->astOperand2()->isNumber()) if (tok->astOperand2() && tok->astOperand2()->isNumber())
numchildren.push_back(MathLib::toLongNumber(tok->astOperand2()->str())); numchildren.push_back(MathLib::toBigNumber(tok->astOperand2()->str()));
else if (tok->astOperand2() && tok->str() == tok->astOperand2()->str()) else if (tok->astOperand2() && tok->str() == tok->astOperand2()->str())
getnumchildren(tok->astOperand2(), numchildren); getnumchildren(tok->astOperand2(), numchildren);
} }
@ -371,7 +371,7 @@ void CheckCondition::comparison()
std::swap(expr1,expr2); std::swap(expr1,expr2);
if (!expr2->isNumber()) if (!expr2->isNumber())
continue; continue;
const MathLib::bigint num2 = MathLib::toLongNumber(expr2->str()); const MathLib::bigint num2 = MathLib::toBigNumber(expr2->str());
if (num2 < 0) if (num2 < 0)
continue; continue;
if (!Token::Match(expr1,"[&|]")) if (!Token::Match(expr1,"[&|]"))
@ -463,8 +463,8 @@ bool CheckCondition::isOverlappingCond(const Token * const cond1, const Token *
if (!isSameExpression(mTokenizer->isCPP(), true, expr1, expr2, mSettings->library, pure, false)) if (!isSameExpression(mTokenizer->isCPP(), true, expr1, expr2, mSettings->library, pure, false))
return false; return false;
const MathLib::bigint value1 = MathLib::toLongNumber(num1->str()); const MathLib::bigint value1 = MathLib::toBigNumber(num1->str());
const MathLib::bigint value2 = MathLib::toLongNumber(num2->str()); const MathLib::bigint value2 = MathLib::toBigNumber(num2->str());
if (cond2->str() == "&") if (cond2->str() == "&")
return ((value1 & value2) == value2); return ((value1 & value2) == value2);
return ((value1 & value2) > 0); return ((value1 & value2) > 0);
@ -1267,11 +1267,11 @@ void CheckCondition::checkIncorrectLogicOperator()
const double d1 = (isfloat) ? MathLib::toDoubleNumber(value1) : 0; const double d1 = (isfloat) ? MathLib::toDoubleNumber(value1) : 0;
const double d2 = (isfloat) ? MathLib::toDoubleNumber(value2) : 0; const double d2 = (isfloat) ? MathLib::toDoubleNumber(value2) : 0;
const MathLib::bigint i1 = (isfloat) ? 0 : MathLib::toLongNumber(value1); const MathLib::bigint i1 = (isfloat) ? 0 : MathLib::toBigNumber(value1);
const MathLib::bigint i2 = (isfloat) ? 0 : MathLib::toLongNumber(value2); const MathLib::bigint i2 = (isfloat) ? 0 : MathLib::toBigNumber(value2);
const bool useUnsignedInt = (std::numeric_limits<MathLib::bigint>::max()==i1) || (std::numeric_limits<MathLib::bigint>::max()==i2); const bool useUnsignedInt = (std::numeric_limits<MathLib::bigint>::max()==i1) || (std::numeric_limits<MathLib::bigint>::max()==i2);
const MathLib::biguint u1 = (useUnsignedInt) ? MathLib::toLongNumber(value1) : 0; const MathLib::biguint u1 = (useUnsignedInt) ? MathLib::toBigNumber(value1) : 0;
const MathLib::biguint u2 = (useUnsignedInt) ? MathLib::toLongNumber(value2) : 0; const MathLib::biguint u2 = (useUnsignedInt) ? MathLib::toBigNumber(value2) : 0;
// evaluate if expression is always true/false // evaluate if expression is always true/false
bool alwaysTrue = true, alwaysFalse = true; bool alwaysTrue = true, alwaysFalse = true;
bool firstTrue = true, secondTrue = true; bool firstTrue = true, secondTrue = true;

View File

@ -438,12 +438,12 @@ void CheckFunctions::checkMathFunctions()
if (tok->strAt(-1) != "." if (tok->strAt(-1) != "."
&& Token::Match(tok, "log|logf|logl|log10|log10f|log10l|log2|log2f|log2l ( %num% )")) { && Token::Match(tok, "log|logf|logl|log10|log10f|log10l|log2|log2f|log2l ( %num% )")) {
const std::string& number = tok->strAt(2); const std::string& number = tok->strAt(2);
if ((MathLib::isInt(number) && MathLib::toLongNumber(number) <= 0) || if ((MathLib::isInt(number) && MathLib::toBigNumber(number) <= 0) ||
(MathLib::isFloat(number) && MathLib::toDoubleNumber(number) <= 0.)) (MathLib::isFloat(number) && MathLib::toDoubleNumber(number) <= 0.))
mathfunctionCallWarning(tok); mathfunctionCallWarning(tok);
} else if (Token::Match(tok, "log1p|log1pf|log1pl ( %num% )")) { } else if (Token::Match(tok, "log1p|log1pf|log1pl ( %num% )")) {
const std::string& number = tok->strAt(2); const std::string& number = tok->strAt(2);
if ((MathLib::isInt(number) && MathLib::toLongNumber(number) <= -1) || if ((MathLib::isInt(number) && MathLib::toBigNumber(number) <= -1) ||
(MathLib::isFloat(number) && MathLib::toDoubleNumber(number) <= -1.)) (MathLib::isFloat(number) && MathLib::toDoubleNumber(number) <= -1.))
mathfunctionCallWarning(tok); mathfunctionCallWarning(tok);
} }
@ -575,7 +575,7 @@ void CheckFunctions::memsetInvalid2ndParam()
} }
if (printWarning && secondParamTok->isNumber()) { // Check if the second parameter is a literal and is out of range if (printWarning && secondParamTok->isNumber()) { // Check if the second parameter is a literal and is out of range
const long long int value = MathLib::toLongNumber(secondParamTok->str()); const long long int value = MathLib::toBigNumber(secondParamTok->str());
const long long sCharMin = mSettings->platform.signedCharMin(); const long long sCharMin = mSettings->platform.signedCharMin();
const long long uCharMax = mSettings->platform.unsignedCharMax(); const long long uCharMax = mSettings->platform.unsignedCharMax();
if (value < sCharMin || value > uCharMax) if (value < sCharMin || value > uCharMax)

View File

@ -435,7 +435,7 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken,
// Assigning non-zero value variable. It might be used to // Assigning non-zero value variable. It might be used to
// track the execution for a later if condition. // track the execution for a later if condition.
if (Token::Match(varTok->tokAt(2), "%num% ;") && MathLib::toLongNumber(varTok->strAt(2)) != 0) if (Token::Match(varTok->tokAt(2), "%num% ;") && MathLib::toBigNumber(varTok->strAt(2)) != 0)
notzero.insert(varTok->varId()); notzero.insert(varTok->varId());
else if (Token::Match(varTok->tokAt(2), "- %type% ;") && varTok->tokAt(3)->isUpperCaseName()) else if (Token::Match(varTok->tokAt(2), "- %type% ;") && varTok->tokAt(3)->isUpperCaseName())
notzero.insert(varTok->varId()); notzero.insert(varTok->varId());

View File

@ -3085,7 +3085,7 @@ void CheckOther::checkIncompleteArrayFill()
if (!var || !var->isArray() || var->dimensions().empty() || !var->dimension(0)) if (!var || !var->isArray() || var->dimensions().empty() || !var->dimension(0))
continue; continue;
if (MathLib::toLongNumber(tok->linkAt(1)->strAt(-1)) == var->dimension(0)) { if (MathLib::toBigNumber(tok->linkAt(1)->strAt(-1)) == var->dimension(0)) {
int size = mTokenizer->sizeOfType(var->typeStartToken()); int size = mTokenizer->sizeOfType(var->typeStartToken());
if (size == 0 && var->valueType()->pointer) if (size == 0 && var->valueType()->pointer)
size = mSettings->platform.sizeof_pointer; size = mSettings->platform.sizeof_pointer;

View File

@ -292,7 +292,7 @@ void CheckString::checkIncorrectStringCompare()
tok = tok->next()->link(); tok = tok->next()->link();
if (Token::simpleMatch(tok, ". substr (") && Token::Match(tok->tokAt(3)->nextArgument(), "%num% )")) { if (Token::simpleMatch(tok, ". substr (") && Token::Match(tok->tokAt(3)->nextArgument(), "%num% )")) {
const MathLib::biguint clen = MathLib::toULongNumber(tok->linkAt(2)->strAt(-1)); const MathLib::biguint clen = MathLib::toBigUNumber(tok->linkAt(2)->strAt(-1));
const Token* begin = tok->previous(); const Token* begin = tok->previous();
for (;;) { // Find start of statement for (;;) { // Find start of statement
while (begin->link() && Token::Match(begin, "]|)|>")) while (begin->link() && Token::Match(begin, "]|)|>"))

View File

@ -315,9 +315,9 @@ static void conditionAlwaysTrueOrFalse(const Token *tok, const std::map<nonneg i
return; return;
if (tok->str() == "==") if (tok->str() == "==")
*alwaysTrue = (it->second == MathLib::toLongNumber(numtok->str())); *alwaysTrue = (it->second == MathLib::toBigNumber(numtok->str()));
else if (tok->str() == "!=") else if (tok->str() == "!=")
*alwaysTrue = (it->second != MathLib::toLongNumber(numtok->str())); *alwaysTrue = (it->second != MathLib::toBigNumber(numtok->str()));
else else
return; return;
*alwaysFalse = !(*alwaysTrue); *alwaysFalse = !(*alwaysTrue);
@ -517,7 +517,7 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const Variable& var
if (Token::Match(tok2, "[;{}.] %name% = - %name% ;")) if (Token::Match(tok2, "[;{}.] %name% = - %name% ;"))
varValueIf[tok2->next()->varId()] = !VariableValue(0); varValueIf[tok2->next()->varId()] = !VariableValue(0);
else if (Token::Match(tok2, "[;{}.] %name% = %num% ;")) else if (Token::Match(tok2, "[;{}.] %name% = %num% ;"))
varValueIf[tok2->next()->varId()] = VariableValue(MathLib::toLongNumber(tok2->strAt(3))); varValueIf[tok2->next()->varId()] = VariableValue(MathLib::toBigNumber(tok2->strAt(3)));
} }
} }
@ -547,7 +547,7 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const Variable& var
if (Token::Match(tok2, "[;{}.] %var% = - %name% ;")) if (Token::Match(tok2, "[;{}.] %var% = - %name% ;"))
varValueElse[tok2->next()->varId()] = !VariableValue(0); varValueElse[tok2->next()->varId()] = !VariableValue(0);
else if (Token::Match(tok2, "[;{}.] %var% = %num% ;")) else if (Token::Match(tok2, "[;{}.] %var% = %num% ;"))
varValueElse[tok2->next()->varId()] = VariableValue(MathLib::toLongNumber(tok2->strAt(3))); varValueElse[tok2->next()->varId()] = VariableValue(MathLib::toBigNumber(tok2->strAt(3)));
} }
} }

View File

@ -734,7 +734,7 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
if (nodeType == BreakStmt) if (nodeType == BreakStmt)
return addtoken(tokenList, "break"); return addtoken(tokenList, "break");
if (nodeType == CharacterLiteral) { if (nodeType == CharacterLiteral) {
const int c = MathLib::toLongNumber(mExtTokens.back()); const int c = MathLib::toBigNumber(mExtTokens.back());
if (c == 0) if (c == 0)
return addtoken(tokenList, "\'\\0\'"); return addtoken(tokenList, "\'\\0\'");
if (c == '\r') if (c == '\r')

View File

@ -916,13 +916,13 @@ bool Library::isIntArgValid(const Token *ftok, int argnr, const MathLib::bigint
TokenList tokenList(nullptr); TokenList tokenList(nullptr);
gettokenlistfromvalid(ac->valid, tokenList); gettokenlistfromvalid(ac->valid, tokenList);
for (const Token *tok = tokenList.front(); tok; tok = tok->next()) { for (const Token *tok = tokenList.front(); tok; tok = tok->next()) {
if (tok->isNumber() && argvalue == MathLib::toLongNumber(tok->str())) if (tok->isNumber() && argvalue == MathLib::toBigNumber(tok->str()))
return true; return true;
if (Token::Match(tok, "%num% : %num%") && argvalue >= MathLib::toLongNumber(tok->str()) && argvalue <= MathLib::toLongNumber(tok->strAt(2))) if (Token::Match(tok, "%num% : %num%") && argvalue >= MathLib::toBigNumber(tok->str()) && argvalue <= MathLib::toBigNumber(tok->strAt(2)))
return true; return true;
if (Token::Match(tok, "%num% : ,") && argvalue >= MathLib::toLongNumber(tok->str())) if (Token::Match(tok, "%num% : ,") && argvalue >= MathLib::toBigNumber(tok->str()))
return true; return true;
if ((!tok->previous() || tok->previous()->str() == ",") && Token::Match(tok,": %num%") && argvalue <= MathLib::toLongNumber(tok->strAt(1))) if ((!tok->previous() || tok->previous()->str() == ",") && Token::Match(tok,": %num%") && argvalue <= MathLib::toBigNumber(tok->strAt(1)))
return true; return true;
} }
return false; return false;

View File

@ -49,7 +49,7 @@ MathLib::value::value(const std::string &s)
throw InternalError(nullptr, "Invalid value: " + s); throw InternalError(nullptr, "Invalid value: " + s);
mType = MathLib::value::Type::INT; mType = MathLib::value::Type::INT;
mIntValue = MathLib::toLongNumber(s); mIntValue = MathLib::toBigNumber(s);
if (isIntHex(s) && mIntValue < 0) if (isIntHex(s) && mIntValue < 0)
mIsUnsigned = true; mIsUnsigned = true;
@ -286,7 +286,7 @@ MathLib::value MathLib::value::shiftRight(const MathLib::value &v) const
} }
// TODO: remove handling of non-literal stuff // TODO: remove handling of non-literal stuff
MathLib::biguint MathLib::toULongNumber(const std::string & str) MathLib::biguint MathLib::toBigUNumber(const std::string & str)
{ {
// hexadecimal numbers: // hexadecimal numbers:
if (isIntHex(str)) { if (isIntHex(str)) {
@ -294,9 +294,9 @@ MathLib::biguint MathLib::toULongNumber(const std::string & str)
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); throw InternalError(nullptr, "Internal Error. MathLib::toBigUNumber: out_of_range: " + str);
} catch (const std::invalid_argument& /*e*/) { } catch (const std::invalid_argument& /*e*/) {
throw InternalError(nullptr, "Internal Error. MathLib::toULongNumber: invalid_argument: " + str); throw InternalError(nullptr, "Internal Error. MathLib::toBigUNumber: invalid_argument: " + str);
} }
} }
@ -306,9 +306,9 @@ MathLib::biguint MathLib::toULongNumber(const std::string & str)
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); throw InternalError(nullptr, "Internal Error. MathLib::toBigUNumber: out_of_range: " + str);
} catch (const std::invalid_argument& /*e*/) { } catch (const std::invalid_argument& /*e*/) {
throw InternalError(nullptr, "Internal Error. MathLib::toULongNumber: invalid_argument: " + str); throw InternalError(nullptr, "Internal Error. MathLib::toBigUNumber: invalid_argument: " + str);
} }
} }
@ -347,13 +347,13 @@ MathLib::biguint MathLib::toULongNumber(const std::string & str)
if (idx != str.size()) { if (idx != str.size()) {
const std::string s = str.substr(idx); const std::string s = str.substr(idx);
if (!isValidIntegerSuffix(s, true)) if (!isValidIntegerSuffix(s, true))
throw InternalError(nullptr, "Internal Error. MathLib::toULongNumber: input was not completely consumed: " + str); throw InternalError(nullptr, "Internal Error. MathLib::toBigUNumber: 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); throw InternalError(nullptr, "Internal Error. MathLib::toBigUNumber: out_of_range: " + str);
} catch (const std::invalid_argument& /*e*/) { } catch (const std::invalid_argument& /*e*/) {
throw InternalError(nullptr, "Internal Error. MathLib::toULongNumber: invalid_argument: " + str); throw InternalError(nullptr, "Internal Error. MathLib::toBigUNumber: invalid_argument: " + str);
} }
} }
@ -365,7 +365,7 @@ unsigned int MathLib::encodeMultiChar(const std::string& str)
} }
// TODO: remove handling of non-literal stuff // TODO: remove handling of non-literal stuff
MathLib::bigint MathLib::toLongNumber(const std::string & str) MathLib::bigint MathLib::toBigNumber(const std::string & str)
{ {
// hexadecimal numbers: // hexadecimal numbers:
if (isIntHex(str)) { if (isIntHex(str)) {
@ -373,9 +373,9 @@ MathLib::bigint MathLib::toLongNumber(const std::string & str)
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); throw InternalError(nullptr, "Internal Error. MathLib::toBigNumber: out_of_range: " + str);
} catch (const std::invalid_argument& /*e*/) { } catch (const std::invalid_argument& /*e*/) {
throw InternalError(nullptr, "Internal Error. MathLib::toLongNumber: invalid_argument: " + str); throw InternalError(nullptr, "Internal Error. MathLib::toBigNumber: invalid_argument: " + str);
} }
} }
@ -385,9 +385,9 @@ MathLib::bigint MathLib::toLongNumber(const std::string & str)
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); throw InternalError(nullptr, "Internal Error. MathLib::toBigNumber: out_of_range: " + str);
} catch (const std::invalid_argument& /*e*/) { } catch (const std::invalid_argument& /*e*/) {
throw InternalError(nullptr, "Internal Error. MathLib::toLongNumber: invalid_argument: " + str); throw InternalError(nullptr, "Internal Error. MathLib::toBigNumber: invalid_argument: " + str);
} }
} }
@ -427,13 +427,13 @@ MathLib::bigint MathLib::toLongNumber(const std::string & str)
if (idx != str.size()) { if (idx != str.size()) {
const std::string s = str.substr(idx); const std::string s = str.substr(idx);
if (!isValidIntegerSuffix(s, true)) if (!isValidIntegerSuffix(s, true))
throw InternalError(nullptr, "Internal Error. MathLib::toLongNumber: input was not completely consumed: " + str); throw InternalError(nullptr, "Internal Error. MathLib::toBigNumber: 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); throw InternalError(nullptr, "Internal Error. MathLib::toBigNumber: out_of_range: " + str);
} catch (const std::invalid_argument& /*e*/) { } catch (const std::invalid_argument& /*e*/) {
throw InternalError(nullptr, "Internal Error. MathLib::toLongNumber: invalid_argument: " + str); throw InternalError(nullptr, "Internal Error. MathLib::toBigNumber: invalid_argument: " + str);
} }
} }
@ -494,7 +494,7 @@ double MathLib::toDoubleNumber(const std::string &str)
} }
} }
if (isIntHex(str)) if (isIntHex(str))
return static_cast<double>(toLongNumber(str)); return static_cast<double>(toBigNumber(str));
#ifdef _LIBCPP_VERSION #ifdef _LIBCPP_VERSION
if (isFloat(str)) // Workaround libc++ bug at https://github.com/llvm/llvm-project/issues/18156 if (isFloat(str)) // Workaround libc++ bug at https://github.com/llvm/llvm-project/issues/18156
// TODO: handle locale // TODO: handle locale
@ -1059,7 +1059,7 @@ std::string MathLib::add(const std::string & first, const std::string & second)
return (value(first) + value(second)).str(); return (value(first) + value(second)).str();
#else #else
if (MathLib::isInt(first) && MathLib::isInt(second)) { if (MathLib::isInt(first) && MathLib::isInt(second)) {
return std::to_string(toLongNumber(first) + toLongNumber(second)) + intsuffix(first, second); return std::to_string(toBigNumber(first) + toBigNumber(second)) + intsuffix(first, second);
} }
double d1 = toDoubleNumber(first); double d1 = toDoubleNumber(first);
@ -1081,7 +1081,7 @@ std::string MathLib::subtract(const std::string &first, const std::string &secon
return (value(first) - value(second)).str(); return (value(first) - value(second)).str();
#else #else
if (MathLib::isInt(first) && MathLib::isInt(second)) { if (MathLib::isInt(first) && MathLib::isInt(second)) {
return std::to_string(toLongNumber(first) - toLongNumber(second)) + intsuffix(first, second); return std::to_string(toBigNumber(first) - toBigNumber(second)) + intsuffix(first, second);
} }
if (first == second) if (first == second)
@ -1106,13 +1106,13 @@ std::string MathLib::divide(const std::string &first, const std::string &second)
return (value(first) / value(second)).str(); return (value(first) / value(second)).str();
#else #else
if (MathLib::isInt(first) && MathLib::isInt(second)) { if (MathLib::isInt(first) && MathLib::isInt(second)) {
const bigint a = toLongNumber(first); const bigint a = toBigNumber(first);
const bigint b = toLongNumber(second); const bigint b = toBigNumber(second);
if (b == 0) if (b == 0)
throw InternalError(nullptr, "Internal Error: Division by zero"); throw InternalError(nullptr, "Internal Error: Division by zero");
if (a == std::numeric_limits<bigint>::min() && std::abs(b)<=1) if (a == std::numeric_limits<bigint>::min() && std::abs(b)<=1)
throw InternalError(nullptr, "Internal Error: Division overflow"); throw InternalError(nullptr, "Internal Error: Division overflow");
return std::to_string(toLongNumber(first) / b) + intsuffix(first, second); return std::to_string(toBigNumber(first) / b) + intsuffix(first, second);
} }
if (isNullValue(second)) { if (isNullValue(second)) {
if (isNullValue(first)) if (isNullValue(first))
@ -1129,7 +1129,7 @@ std::string MathLib::multiply(const std::string &first, const std::string &secon
return (value(first) * value(second)).str(); return (value(first) * value(second)).str();
#else #else
if (MathLib::isInt(first) && MathLib::isInt(second)) { if (MathLib::isInt(first) && MathLib::isInt(second)) {
return std::to_string(toLongNumber(first) * toLongNumber(second)) + intsuffix(first, second); return std::to_string(toBigNumber(first) * toBigNumber(second)) + intsuffix(first, second);
} }
return toString(toDoubleNumber(first) * toDoubleNumber(second)); return toString(toDoubleNumber(first) * toDoubleNumber(second));
#endif #endif
@ -1141,10 +1141,10 @@ std::string MathLib::mod(const std::string &first, const std::string &second)
return (value(first) % value(second)).str(); return (value(first) % value(second)).str();
#else #else
if (MathLib::isInt(first) && MathLib::isInt(second)) { if (MathLib::isInt(first) && MathLib::isInt(second)) {
const bigint b = toLongNumber(second); const bigint b = toBigNumber(second);
if (b == 0) if (b == 0)
throw InternalError(nullptr, "Internal Error: Division by zero"); throw InternalError(nullptr, "Internal Error: Division by zero");
return std::to_string(toLongNumber(first) % b) + intsuffix(first, second); return std::to_string(toBigNumber(first) % b) + intsuffix(first, second);
} }
return toString(std::fmod(toDoubleNumber(first),toDoubleNumber(second))); return toString(std::fmod(toDoubleNumber(first),toDoubleNumber(second)));
#endif #endif
@ -1169,13 +1169,13 @@ std::string MathLib::calculate(const std::string &first, const std::string &seco
return MathLib::mod(first, second); return MathLib::mod(first, second);
case '&': case '&':
return std::to_string(MathLib::toLongNumber(first) & MathLib::toLongNumber(second)) + intsuffix(first,second); return std::to_string(MathLib::toBigNumber(first) & MathLib::toBigNumber(second)) + intsuffix(first, second);
case '|': case '|':
return std::to_string(MathLib::toLongNumber(first) | MathLib::toLongNumber(second)) + intsuffix(first,second); return std::to_string(MathLib::toBigNumber(first) | MathLib::toBigNumber(second)) + intsuffix(first, second);
case '^': case '^':
return std::to_string(MathLib::toLongNumber(first) ^ MathLib::toLongNumber(second)) + intsuffix(first,second); return std::to_string(MathLib::toBigNumber(first) ^ MathLib::toBigNumber(second)) + intsuffix(first, second);
default: default:
throw InternalError(nullptr, std::string("Unexpected action '") + action + "' in MathLib::calculate(). Please report this to Cppcheck developers."); throw InternalError(nullptr, std::string("Unexpected action '") + action + "' in MathLib::calculate(). Please report this to Cppcheck developers.");

View File

@ -70,9 +70,9 @@ public:
static const int bigint_bits; static const int bigint_bits;
/** @brief for conversion of numeric literals - for atoi-like conversions please use strToInt() */ /** @brief for conversion of numeric literals - for atoi-like conversions please use strToInt() */
static bigint toLongNumber(const std::string & str); static bigint toBigNumber(const std::string & str);
/** @brief for conversion of numeric literals - for atoi-like conversions please use strToInt() */ /** @brief for conversion of numeric literals - for atoi-like conversions please use strToInt() */
static biguint toULongNumber(const std::string & str); static biguint toBigUNumber(const std::string & str);
template<class T> static std::string toString(T value) = delete; template<class T> static std::string toString(T value) = delete;
/** @brief for conversion of numeric literals */ /** @brief for conversion of numeric literals */

View File

@ -1218,7 +1218,7 @@ struct Executor {
if (expr->isNumber()) { if (expr->isNumber()) {
if (MathLib::isFloat(expr->str())) if (MathLib::isFloat(expr->str()))
return unknown; return unknown;
MathLib::bigint i = MathLib::toLongNumber(expr->str()); MathLib::bigint i = MathLib::toBigNumber(expr->str());
if (i < 0 && astIsUnsigned(expr)) if (i < 0 && astIsUnsigned(expr))
return unknown; return unknown;
return ValueFlow::Value{i}; return ValueFlow::Value{i};

View File

@ -1754,7 +1754,7 @@ void SymbolDatabase::setArrayDimensionsUsingValueFlow()
if (Token::Match(tokenList.front(), "; %num% ;")) { if (Token::Match(tokenList.front(), "; %num% ;")) {
dimension.known = true; dimension.known = true;
dimension.num = MathLib::toLongNumber(tokenList.front()->next()->str()); dimension.num = MathLib::toBigNumber(tokenList.front()->next()->str());
} }
continue; continue;
@ -2142,7 +2142,7 @@ Variable::Variable(const Token *name_, const std::string &clangType, const Token
dim.tok = nullptr; dim.tok = nullptr;
dim.known = pos > pos1; dim.known = pos > pos1;
if (pos > pos1) if (pos > pos1)
dim.num = MathLib::toLongNumber(clangType.substr(pos1, pos-pos1)); dim.num = MathLib::toBigNumber(clangType.substr(pos1, pos - pos1));
else else
dim.num = 0; dim.num = 0;
mDimensions.push_back(dim); mDimensions.push_back(dim);
@ -3597,7 +3597,7 @@ bool Variable::arrayDimensions(const Settings* settings, bool& isContainer)
if (Token::Match(tok, "%num% [,>]")) { if (Token::Match(tok, "%num% [,>]")) {
dimension_.tok = tok; dimension_.tok = tok;
dimension_.known = true; dimension_.known = true;
dimension_.num = MathLib::toLongNumber(tok->str()); dimension_.num = MathLib::toBigNumber(tok->str());
} else if (tok) { } else if (tok) {
dimension_.tok = tok; dimension_.tok = tok;
dimension_.known = false; dimension_.known = false;
@ -7139,7 +7139,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to
const bool unsignedSuffix = (tokStr.find_last_of("uU") != std::string::npos); const bool unsignedSuffix = (tokStr.find_last_of("uU") != std::string::npos);
ValueType::Sign sign = unsignedSuffix ? ValueType::Sign::UNSIGNED : ValueType::Sign::SIGNED; ValueType::Sign sign = unsignedSuffix ? ValueType::Sign::UNSIGNED : ValueType::Sign::SIGNED;
ValueType::Type type = ValueType::Type::INT; ValueType::Type type = ValueType::Type::INT;
const MathLib::biguint value = MathLib::toULongNumber(tokStr); const MathLib::biguint value = MathLib::toBigUNumber(tokStr);
for (std::size_t pos = tokStr.size() - 1U; pos > 0U; --pos) { for (std::size_t pos = tokStr.size() - 1U; pos > 0U; --pos) {
const char suffix = tokStr[pos]; const char suffix = tokStr[pos];
if (suffix == 'u' || suffix == 'U') if (suffix == 'u' || suffix == 'U')

View File

@ -2507,9 +2507,9 @@ void TemplateSimplifier::simplifyTemplateArgs(Token *start, const Token *end, st
MathLib::isInt(tok->strAt(2))) { MathLib::isInt(tok->strAt(2))) {
if ((Token::Match(tok->previous(), "(|&&|%oror%|,") || tok == start) && if ((Token::Match(tok->previous(), "(|&&|%oror%|,") || tok == start) &&
(Token::Match(tok->tokAt(3), ")|&&|%oror%|?") || tok->tokAt(3) == end)) { (Token::Match(tok->tokAt(3), ")|&&|%oror%|?") || tok->tokAt(3) == end)) {
const MathLib::bigint op1(MathLib::toLongNumber(tok->str())); const MathLib::bigint op1(MathLib::toBigNumber(tok->str()));
const std::string &cmp(tok->next()->str()); const std::string &cmp(tok->next()->str());
const MathLib::bigint op2(MathLib::toLongNumber(tok->strAt(2))); const MathLib::bigint op2(MathLib::toBigNumber(tok->strAt(2)));
std::string result; std::string result;
@ -2680,7 +2680,7 @@ bool TemplateSimplifier::simplifyCalculations(Token* frontToken, const Token *ba
if (validTokenEnd(bounded, tok, backToken, 3) && if (validTokenEnd(bounded, tok, backToken, 3) &&
Token::Match(tok->previous(), "(|&&|%oror% %char% %comp% %num% &&|%oror%|)")) { Token::Match(tok->previous(), "(|&&|%oror% %char% %comp% %num% &&|%oror%|)")) {
tok->str(std::to_string(MathLib::toLongNumber(tok->str()))); tok->str(std::to_string(MathLib::toBigNumber(tok->str())));
} }
if (validTokenEnd(bounded, tok, backToken, 5) && if (validTokenEnd(bounded, tok, backToken, 5) &&
@ -2876,9 +2876,9 @@ bool TemplateSimplifier::simplifyCalculations(Token* frontToken, const Token *ba
if (validTokenStart(bounded, tok, frontToken, -1) && if (validTokenStart(bounded, tok, frontToken, -1) &&
Token::Match(tok->previous(), "(|&&|%oror%") && Token::Match(tok->previous(), "(|&&|%oror%") &&
Token::Match(tok->tokAt(3), ")|&&|%oror%|?")) { Token::Match(tok->tokAt(3), ")|&&|%oror%|?")) {
const MathLib::bigint op1(MathLib::toLongNumber(tok->str())); const MathLib::bigint op1(MathLib::toBigNumber(tok->str()));
const std::string &cmp(tok->next()->str()); const std::string &cmp(tok->next()->str());
const MathLib::bigint op2(MathLib::toLongNumber(tok->strAt(2))); const MathLib::bigint op2(MathLib::toBigNumber(tok->strAt(2)));
std::string result; std::string result;

View File

@ -3785,7 +3785,7 @@ void Tokenizer::arraySize()
if (tok2->link() && Token::Match(tok2, "{|(|[|<")) { if (tok2->link() && Token::Match(tok2, "{|(|[|<")) {
if (tok2->str() == "[" && tok2->link()->strAt(1) == "=") { // designated initializer if (tok2->str() == "[" && tok2->link()->strAt(1) == "=") { // designated initializer
if (Token::Match(tok2, "[ %num% ]")) if (Token::Match(tok2, "[ %num% ]"))
sz = std::max(sz, MathLib::toULongNumber(tok2->strAt(1)) + 1U); sz = std::max(sz, MathLib::toBigUNumber(tok2->strAt(1)) + 1U);
else { else {
sz = 0; sz = 0;
break; break;
@ -3926,8 +3926,8 @@ void Tokenizer::simplifyCaseRange()
{ {
for (Token* tok = list.front(); tok; tok = tok->next()) { for (Token* tok = list.front(); tok; tok = tok->next()) {
if (Token::Match(tok, "case %num%|%char% ... %num%|%char% :")) { if (Token::Match(tok, "case %num%|%char% ... %num%|%char% :")) {
const MathLib::bigint start = MathLib::toLongNumber(tok->strAt(1)); const MathLib::bigint start = MathLib::toBigNumber(tok->strAt(1));
MathLib::bigint end = MathLib::toLongNumber(tok->strAt(3)); MathLib::bigint end = MathLib::toBigNumber(tok->strAt(3));
end = std::min(start + 50, end); // Simplify it 50 times at maximum end = std::min(start + 50, end); // Simplify it 50 times at maximum
if (start < end) { if (start < end) {
tok = tok->tokAt(2); tok = tok->tokAt(2);
@ -8022,7 +8022,7 @@ void Tokenizer::unhandledCharLiteral(const Token *tok, const std::string& msg) c
static bool isNumberOneOf(const std::string &s, MathLib::bigint intConstant, const char* floatConstant) static bool isNumberOneOf(const std::string &s, MathLib::bigint intConstant, const char* floatConstant)
{ {
if (MathLib::isInt(s)) { if (MathLib::isInt(s)) {
if (MathLib::toLongNumber(s) == intConstant) if (MathLib::toBigNumber(s) == intConstant)
return true; return true;
} else if (MathLib::isFloat(s)) { } else if (MathLib::isFloat(s)) {
if (MathLib::toString(MathLib::toDoubleNumber(s)) == floatConstant) if (MathLib::toString(MathLib::toDoubleNumber(s)) == floatConstant)
@ -9056,9 +9056,11 @@ void Tokenizer::simplifyCppcheckAttribute()
if (vartok->isName()) { if (vartok->isName()) {
if (Token::Match(tok->previous(), "__cppcheck_low__ ( %num% )")) if (Token::Match(tok->previous(), "__cppcheck_low__ ( %num% )"))
vartok->setCppcheckAttribute(TokenImpl::CppcheckAttributes::Type::LOW, MathLib::toLongNumber(tok->next()->str())); vartok->setCppcheckAttribute(TokenImpl::CppcheckAttributes::Type::LOW,
MathLib::toBigNumber(tok->next()->str()));
else if (Token::Match(tok->previous(), "__cppcheck_high__ ( %num% )")) else if (Token::Match(tok->previous(), "__cppcheck_high__ ( %num% )"))
vartok->setCppcheckAttribute(TokenImpl::CppcheckAttributes::Type::HIGH, MathLib::toLongNumber(tok->next()->str())); vartok->setCppcheckAttribute(TokenImpl::CppcheckAttributes::Type::HIGH,
MathLib::toBigNumber(tok->next()->str()));
} }
// Delete cppcheck attribute.. // Delete cppcheck attribute..
@ -9121,13 +9123,17 @@ void Tokenizer::simplifyCPPAttribute()
} }
if (argtok && argtok->str() == vartok->str()) { if (argtok && argtok->str() == vartok->str()) {
if (vartok->next()->str() == ">=") if (vartok->next()->str() == ">=")
argtok->setCppcheckAttribute(TokenImpl::CppcheckAttributes::Type::LOW, MathLib::toLongNumber(vartok->strAt(2))); argtok->setCppcheckAttribute(TokenImpl::CppcheckAttributes::Type::LOW,
MathLib::toBigNumber(vartok->strAt(2)));
else if (vartok->next()->str() == ">") else if (vartok->next()->str() == ">")
argtok->setCppcheckAttribute(TokenImpl::CppcheckAttributes::Type::LOW, MathLib::toLongNumber(vartok->strAt(2))+1); argtok->setCppcheckAttribute(TokenImpl::CppcheckAttributes::Type::LOW,
MathLib::toBigNumber(vartok->strAt(2)) + 1);
else if (vartok->next()->str() == "<=") else if (vartok->next()->str() == "<=")
argtok->setCppcheckAttribute(TokenImpl::CppcheckAttributes::Type::HIGH, MathLib::toLongNumber(vartok->strAt(2))); argtok->setCppcheckAttribute(TokenImpl::CppcheckAttributes::Type::HIGH,
MathLib::toBigNumber(vartok->strAt(2)));
else if (vartok->next()->str() == "<") else if (vartok->next()->str() == "<")
argtok->setCppcheckAttribute(TokenImpl::CppcheckAttributes::Type::HIGH, MathLib::toLongNumber(vartok->strAt(2))-1); argtok->setCppcheckAttribute(TokenImpl::CppcheckAttributes::Type::HIGH,
MathLib::toBigNumber(vartok->strAt(2)) - 1);
} }
} }
} else { } else {
@ -9563,7 +9569,7 @@ void Tokenizer::simplifyBitfields()
!Token::simpleMatch(tok->tokAt(2), "default :")) { !Token::simpleMatch(tok->tokAt(2), "default :")) {
Token *tok1 = (tok->next()->str() == "const") ? tok->tokAt(3) : tok->tokAt(2); Token *tok1 = (tok->next()->str() == "const") ? tok->tokAt(3) : tok->tokAt(2);
if (Token::Match(tok1, "%name% : %num% [;=]")) if (Token::Match(tok1, "%name% : %num% [;=]"))
tok1->setBits(MathLib::toLongNumber(tok1->strAt(2))); tok1->setBits(MathLib::toBigNumber(tok1->strAt(2)));
if (tok1 && tok1->tokAt(2) && if (tok1 && tok1->tokAt(2) &&
(Token::Match(tok1->tokAt(2), "%bool%|%num%") || (Token::Match(tok1->tokAt(2), "%bool%|%num%") ||
!Token::Match(tok1->tokAt(2), "public|protected|private| %type% ::|<|,|{|;"))) { !Token::Match(tok1->tokAt(2), "public|protected|private| %type% ::|<|,|{|;"))) {

View File

@ -1135,7 +1135,7 @@ static Token * valueFlowSetConstantValue(Token *tok, const Settings *settings, b
{ {
if ((tok->isNumber() && MathLib::isInt(tok->str())) || (tok->tokType() == Token::eChar)) { if ((tok->isNumber() && MathLib::isInt(tok->str())) || (tok->tokType() == Token::eChar)) {
try { try {
MathLib::bigint signedValue = MathLib::toLongNumber(tok->str()); MathLib::bigint signedValue = MathLib::toBigNumber(tok->str());
const ValueType* vt = tok->valueType(); const ValueType* vt = tok->valueType();
if (vt && vt->sign == ValueType::UNSIGNED && signedValue < 0 && ValueFlow::getSizeOf(*vt, settings) < sizeof(MathLib::bigint)) { if (vt && vt->sign == ValueType::UNSIGNED && signedValue < 0 && ValueFlow::getSizeOf(*vt, settings) < sizeof(MathLib::bigint)) {
MathLib::bigint minValue{}, maxValue{}; MathLib::bigint minValue{}, maxValue{};
@ -1306,7 +1306,7 @@ static Token * valueFlowSetConstantValue(Token *tok, const Settings *settings, b
const Token* num = brac->astOperand2(); const Token* num = brac->astOperand2();
if (num && ((num->isNumber() && MathLib::isInt(num->str())) || num->tokType() == Token::eChar)) { if (num && ((num->isNumber() && MathLib::isInt(num->str())) || num->tokType() == Token::eChar)) {
try { try {
const MathLib::biguint dim = MathLib::toULongNumber(num->str()); const MathLib::biguint dim = MathLib::toBigUNumber(num->str());
sz *= dim; sz *= dim;
brac = brac->astParent(); brac = brac->astParent();
continue; continue;
@ -1616,9 +1616,9 @@ static void valueFlowBitAnd(TokenList &tokenlist, const Settings* settings)
MathLib::bigint number; MathLib::bigint number;
if (MathLib::isInt(tok->astOperand1()->str())) if (MathLib::isInt(tok->astOperand1()->str()))
number = MathLib::toLongNumber(tok->astOperand1()->str()); number = MathLib::toBigNumber(tok->astOperand1()->str());
else if (MathLib::isInt(tok->astOperand2()->str())) else if (MathLib::isInt(tok->astOperand2()->str()))
number = MathLib::toLongNumber(tok->astOperand2()->str()); number = MathLib::toBigNumber(tok->astOperand2()->str());
else else
continue; continue;
@ -7440,7 +7440,7 @@ static void valueFlowSwitchVariable(TokenList &tokenlist, const SymbolDatabase&
} }
if (Token::Match(tok, "case %num% :")) { if (Token::Match(tok, "case %num% :")) {
std::list<ValueFlow::Value> values; std::list<ValueFlow::Value> values;
values.emplace_back(MathLib::toLongNumber(tok->next()->str())); values.emplace_back(MathLib::toBigNumber(tok->next()->str()));
values.back().condition = tok; values.back().condition = tok;
values.back().errorPath.emplace_back(tok, "case " + tok->next()->str() + ": " + vartok->str() + " is " + tok->next()->str() + " here."); values.back().errorPath.emplace_back(tok, "case " + tok->next()->str() + ": " + vartok->str() + " is " + tok->next()->str() + " here.");
bool known = false; bool known = false;
@ -7451,7 +7451,7 @@ static void valueFlowSwitchVariable(TokenList &tokenlist, const SymbolDatabase&
tok = tok->tokAt(3); tok = tok->tokAt(3);
if (!tok->isName()) if (!tok->isName())
tok = tok->next(); tok = tok->next();
values.emplace_back(MathLib::toLongNumber(tok->next()->str())); values.emplace_back(MathLib::toBigNumber(tok->next()->str()));
values.back().condition = tok; values.back().condition = tok;
values.back().errorPath.emplace_back(tok, "case " + tok->next()->str() + ": " + vartok->str() + " is " + tok->next()->str() + " here."); values.back().errorPath.emplace_back(tok, "case " + tok->next()->str() + ": " + vartok->str() + " is " + tok->next()->str() + " here.");
} }

View File

@ -185,7 +185,7 @@ void CheckOther::invalidFunctionUsage()
{ {
// convert next token into a number // convert next token into a number
MathLib::bigint radix; MathLib::bigint radix;
radix = MathLib::toLongNumber(tok2-&gt;strAt(1)); radix = MathLib::toBigNumber(tok2-&gt;strAt(1));
// invalid radix? // invalid radix?
if (!(radix == 0 || (radix &gt;= 2 &amp;&amp; radix &lt;= 36))) if (!(radix == 0 || (radix &gt;= 2 &amp;&amp; radix &lt;= 36)))

View File

@ -53,8 +53,8 @@ private:
TEST_CASE(calculate); TEST_CASE(calculate);
TEST_CASE(calculate1); TEST_CASE(calculate1);
TEST_CASE(typesuffix); TEST_CASE(typesuffix);
TEST_CASE(toLongNumber); TEST_CASE(toBigNumber);
TEST_CASE(toULongNumber); TEST_CASE(toBigUNumber);
TEST_CASE(toDoubleNumber); TEST_CASE(toDoubleNumber);
TEST_CASE(naninf); TEST_CASE(naninf);
TEST_CASE(isNullValue); TEST_CASE(isNullValue);
@ -250,160 +250,164 @@ private:
ASSERT_EQUALS("2ULL", MathLib::add("1ULL", "1LLU")); ASSERT_EQUALS("2ULL", MathLib::add("1ULL", "1LLU"));
} }
void toLongNumber() const { void toBigNumber() const {
// zero input // zero input
ASSERT_EQUALS(0, MathLib::toLongNumber("0")); ASSERT_EQUALS(0, MathLib::toBigNumber("0"));
ASSERT_EQUALS(0, MathLib::toLongNumber("-0")); ASSERT_EQUALS(0, MathLib::toBigNumber("-0"));
ASSERT_EQUALS(0, MathLib::toLongNumber("+0")); ASSERT_EQUALS(0, MathLib::toBigNumber("+0"));
ASSERT_EQUALS(0, MathLib::toLongNumber("0L")); ASSERT_EQUALS(0, MathLib::toBigNumber("0L"));
ASSERT_EQUALS(0, MathLib::toLongNumber("0l")); ASSERT_EQUALS(0, MathLib::toBigNumber("0l"));
ASSERT_EQUALS(0, MathLib::toLongNumber("0LL")); ASSERT_EQUALS(0, MathLib::toBigNumber("0LL"));
ASSERT_EQUALS(0, MathLib::toLongNumber("0ll")); ASSERT_EQUALS(0, MathLib::toBigNumber("0ll"));
ASSERT_EQUALS(0, MathLib::toLongNumber("0U")); ASSERT_EQUALS(0, MathLib::toBigNumber("0U"));
ASSERT_EQUALS(0, MathLib::toLongNumber("0u")); ASSERT_EQUALS(0, MathLib::toBigNumber("0u"));
ASSERT_EQUALS(0, MathLib::toLongNumber("0UL")); ASSERT_EQUALS(0, MathLib::toBigNumber("0UL"));
ASSERT_EQUALS(0, MathLib::toLongNumber("0ul")); ASSERT_EQUALS(0, MathLib::toBigNumber("0ul"));
ASSERT_EQUALS(0, MathLib::toLongNumber("0ULL")); ASSERT_EQUALS(0, MathLib::toBigNumber("0ULL"));
ASSERT_EQUALS(0, MathLib::toLongNumber("0ull")); ASSERT_EQUALS(0, MathLib::toBigNumber("0ull"));
ASSERT_EQUALS(0, MathLib::toLongNumber("0i64")); // Visual Studio-specific ASSERT_EQUALS(0, MathLib::toBigNumber("0i64")); // Visual Studio-specific
ASSERT_EQUALS(0, MathLib::toLongNumber("0ui64")); // Visual Studio-specific ASSERT_EQUALS(0, MathLib::toBigNumber("0ui64")); // Visual Studio-specific
// TODO: needs to fail // TODO: needs to fail
//ASSERT_EQUALS(0, MathLib::toLongNumber("0lll")); //ASSERT_EQUALS(0, MathLib::toBigNumber("0lll"));
//ASSERT_EQUALS(0, MathLib::toLongNumber("0uu")); //ASSERT_EQUALS(0, MathLib::toBigNumber("0uu"));
ASSERT_EQUALS(1U, MathLib::toLongNumber("1U")); ASSERT_EQUALS(1U, MathLib::toBigNumber("1U"));
ASSERT_EQUALS(10000U, MathLib::toLongNumber("1e4")); ASSERT_EQUALS(10000U, MathLib::toBigNumber("1e4"));
ASSERT_EQUALS(10000U, MathLib::toLongNumber("1e4")); ASSERT_EQUALS(10000U, MathLib::toBigNumber("1e4"));
ASSERT_EQUALS(0xFF00000000000000UL, MathLib::toLongNumber("0xFF00000000000000UL")); ASSERT_EQUALS(0xFF00000000000000UL, MathLib::toBigNumber("0xFF00000000000000UL"));
ASSERT_EQUALS(0x0A00000000000000UL, MathLib::toLongNumber("0x0A00000000000000UL")); ASSERT_EQUALS(0x0A00000000000000UL, MathLib::toBigNumber("0x0A00000000000000UL"));
// from hex // from hex
ASSERT_EQUALS(0, MathLib::toLongNumber("0x0")); ASSERT_EQUALS(0, MathLib::toBigNumber("0x0"));
ASSERT_EQUALS(0, MathLib::toLongNumber("-0x0")); ASSERT_EQUALS(0, MathLib::toBigNumber("-0x0"));
ASSERT_EQUALS(0, MathLib::toLongNumber("+0x0")); ASSERT_EQUALS(0, MathLib::toBigNumber("+0x0"));
ASSERT_EQUALS(10, MathLib::toLongNumber("0xa")); ASSERT_EQUALS(10, MathLib::toBigNumber("0xa"));
ASSERT_EQUALS(10995, MathLib::toLongNumber("0x2AF3")); ASSERT_EQUALS(10995, MathLib::toBigNumber("0x2AF3"));
ASSERT_EQUALS(-10, MathLib::toLongNumber("-0xa")); ASSERT_EQUALS(-10, MathLib::toBigNumber("-0xa"));
ASSERT_EQUALS(-10995, MathLib::toLongNumber("-0x2AF3")); ASSERT_EQUALS(-10995, MathLib::toBigNumber("-0x2AF3"));
ASSERT_EQUALS(10, MathLib::toLongNumber("+0xa")); ASSERT_EQUALS(10, MathLib::toBigNumber("+0xa"));
ASSERT_EQUALS(10995, MathLib::toLongNumber("+0x2AF3")); ASSERT_EQUALS(10995, MathLib::toBigNumber("+0x2AF3"));
// from octal // from octal
ASSERT_EQUALS(8, MathLib::toLongNumber("010")); ASSERT_EQUALS(8, MathLib::toBigNumber("010"));
ASSERT_EQUALS(8, MathLib::toLongNumber("+010")); ASSERT_EQUALS(8, MathLib::toBigNumber("+010"));
ASSERT_EQUALS(-8, MathLib::toLongNumber("-010")); ASSERT_EQUALS(-8, MathLib::toBigNumber("-010"));
ASSERT_EQUALS(125, MathLib::toLongNumber("0175")); ASSERT_EQUALS(125, MathLib::toBigNumber("0175"));
ASSERT_EQUALS(125, MathLib::toLongNumber("+0175")); ASSERT_EQUALS(125, MathLib::toBigNumber("+0175"));
ASSERT_EQUALS(-125, MathLib::toLongNumber("-0175")); ASSERT_EQUALS(-125, MathLib::toBigNumber("-0175"));
// from binary // from binary
ASSERT_EQUALS(0, MathLib::toLongNumber("0b0")); ASSERT_EQUALS(0, MathLib::toBigNumber("0b0"));
ASSERT_EQUALS(1, MathLib::toLongNumber("0b1")); ASSERT_EQUALS(1, MathLib::toBigNumber("0b1"));
ASSERT_EQUALS(1, MathLib::toLongNumber("0b1U")); ASSERT_EQUALS(1, MathLib::toBigNumber("0b1U"));
ASSERT_EQUALS(1, MathLib::toLongNumber("0b1L")); ASSERT_EQUALS(1, MathLib::toBigNumber("0b1L"));
ASSERT_EQUALS(1, MathLib::toLongNumber("0b1LU")); ASSERT_EQUALS(1, MathLib::toBigNumber("0b1LU"));
ASSERT_EQUALS(1, MathLib::toLongNumber("0b1LL")); ASSERT_EQUALS(1, MathLib::toBigNumber("0b1LL"));
ASSERT_EQUALS(1, MathLib::toLongNumber("0b1LLU")); ASSERT_EQUALS(1, MathLib::toBigNumber("0b1LLU"));
ASSERT_EQUALS(1, MathLib::toLongNumber("+0b1")); ASSERT_EQUALS(1, MathLib::toBigNumber("+0b1"));
ASSERT_EQUALS(-1, MathLib::toLongNumber("-0b1")); ASSERT_EQUALS(-1, MathLib::toBigNumber("-0b1"));
ASSERT_EQUALS(9U, MathLib::toLongNumber("011")); ASSERT_EQUALS(9U, MathLib::toBigNumber("011"));
ASSERT_EQUALS(5U, MathLib::toLongNumber("0b101")); ASSERT_EQUALS(5U, MathLib::toBigNumber("0b101"));
ASSERT_EQUALS(215, MathLib::toLongNumber("0b11010111")); ASSERT_EQUALS(215, MathLib::toBigNumber("0b11010111"));
ASSERT_EQUALS(-215, MathLib::toLongNumber("-0b11010111")); ASSERT_EQUALS(-215, MathLib::toBigNumber("-0b11010111"));
ASSERT_EQUALS(215, MathLib::toLongNumber("0B11010111")); ASSERT_EQUALS(215, MathLib::toBigNumber("0B11010111"));
// from base 10 // from base 10
ASSERT_EQUALS(10, MathLib::toLongNumber("10")); ASSERT_EQUALS(10, MathLib::toBigNumber("10"));
ASSERT_EQUALS(10, MathLib::toLongNumber("10.")); ASSERT_EQUALS(10, MathLib::toBigNumber("10."));
ASSERT_EQUALS(10, MathLib::toLongNumber("10.0")); ASSERT_EQUALS(10, MathLib::toBigNumber("10.0"));
ASSERT_EQUALS(100, MathLib::toLongNumber("10E+1")); ASSERT_EQUALS(100, MathLib::toBigNumber("10E+1"));
ASSERT_EQUALS(1, MathLib::toLongNumber("10E-1")); ASSERT_EQUALS(1, MathLib::toBigNumber("10E-1"));
ASSERT_EQUALS(100, MathLib::toLongNumber("+10E+1")); ASSERT_EQUALS(100, MathLib::toBigNumber("+10E+1"));
ASSERT_EQUALS(-1, MathLib::toLongNumber("-10E-1")); ASSERT_EQUALS(-1, MathLib::toBigNumber("-10E-1"));
ASSERT_EQUALS(100, MathLib::toLongNumber("+10.E+1")); ASSERT_EQUALS(100, MathLib::toBigNumber("+10.E+1"));
ASSERT_EQUALS(-1, MathLib::toLongNumber("-10.E-1")); ASSERT_EQUALS(-1, MathLib::toBigNumber("-10.E-1"));
ASSERT_EQUALS(100, MathLib::toLongNumber("+10.0E+1")); ASSERT_EQUALS(100, MathLib::toBigNumber("+10.0E+1"));
ASSERT_EQUALS(-1, MathLib::toLongNumber("-10.0E-1")); ASSERT_EQUALS(-1, MathLib::toBigNumber("-10.0E-1"));
// from char // from char
ASSERT_EQUALS((int)('A'), MathLib::toLongNumber("'A'")); ASSERT_EQUALS((int)('A'), MathLib::toBigNumber("'A'"));
ASSERT_EQUALS((int)('\x10'), MathLib::toLongNumber("'\\x10'")); ASSERT_EQUALS((int)('\x10'), MathLib::toBigNumber("'\\x10'"));
ASSERT_EQUALS((int)('\100'), MathLib::toLongNumber("'\\100'")); ASSERT_EQUALS((int)('\100'), MathLib::toBigNumber("'\\100'"));
ASSERT_EQUALS((int)('\200'), MathLib::toLongNumber("'\\200'")); ASSERT_EQUALS((int)('\200'), MathLib::toBigNumber("'\\200'"));
ASSERT_EQUALS((int)(L'A'), MathLib::toLongNumber("L'A'")); ASSERT_EQUALS((int)(L'A'), MathLib::toBigNumber("L'A'"));
ASSERT_EQUALS(-8552249625308161526, MathLib::toLongNumber("0x89504e470d0a1a0a")); ASSERT_EQUALS(-8552249625308161526, MathLib::toBigNumber("0x89504e470d0a1a0a"));
ASSERT_EQUALS(-8481036456200365558, MathLib::toLongNumber("0x8a4d4e470d0a1a0a")); ASSERT_EQUALS(-8481036456200365558, MathLib::toBigNumber("0x8a4d4e470d0a1a0a"));
// from long long // from long long
/* /*
* ASSERT_EQUALS(0xFF00000000000000LL, MathLib::toLongNumber("0xFF00000000000000LL")); * ASSERT_EQUALS(0xFF00000000000000LL, MathLib::toBigNumber("0xFF00000000000000LL"));
* This does not work in a portable way! * 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) * While it succeeds on 32bit Visual Studio it fails on Linux 64bit because it is greater than 0x7FFFFFFFFFFFFFFF (=LLONG_MAX)
*/ */
ASSERT_EQUALS(0x0A00000000000000LL, MathLib::toLongNumber("0x0A00000000000000LL")); ASSERT_EQUALS(0x0A00000000000000LL, MathLib::toBigNumber("0x0A00000000000000LL"));
// min/max numeric limits // min/max numeric limits
ASSERT_EQUALS(std::numeric_limits<long long>::min(), MathLib::toLongNumber(std::to_string(std::numeric_limits<long long>::min()))); ASSERT_EQUALS(std::numeric_limits<long long>::min(),
ASSERT_EQUALS(std::numeric_limits<long long>::max(), MathLib::toLongNumber(std::to_string(std::numeric_limits<long long>::max()))); MathLib::toBigNumber(std::to_string(std::numeric_limits<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<long long>::max(),
ASSERT_EQUALS(std::numeric_limits<unsigned long long>::max(), MathLib::toLongNumber(std::to_string(std::numeric_limits<unsigned long long>::max()))); MathLib::toBigNumber(std::to_string(std::numeric_limits<long long>::max())));
ASSERT_EQUALS(std::numeric_limits<unsigned long long>::min(),
MathLib::toBigNumber(std::to_string(std::numeric_limits<unsigned long long>::min())));
ASSERT_EQUALS(std::numeric_limits<unsigned long long>::max(),
MathLib::toBigNumber(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::toBigNumber(std::to_string(i)));
ASSERT_EQUALS(i, MathLib::toLongNumber("0xFFFFFFFFFFFFFFFF")); ASSERT_EQUALS(i, MathLib::toBigNumber("0xFFFFFFFFFFFFFFFF"));
} }
{ {
const MathLib::bigint i = -0xFFFFFFFFFFFFFFFF; const MathLib::bigint i = -0xFFFFFFFFFFFFFFFF;
ASSERT_EQUALS(i, MathLib::toLongNumber(std::to_string(i))); ASSERT_EQUALS(i, MathLib::toBigNumber(std::to_string(i)));
ASSERT_EQUALS(i, MathLib::toLongNumber("-0xFFFFFFFFFFFFFFFF")); ASSERT_EQUALS(i, MathLib::toBigNumber("-0xFFFFFFFFFFFFFFFF"));
} }
ASSERT_THROW_EQUALS(MathLib::toLongNumber("0x10000000000000000"), InternalError, "Internal Error. MathLib::toLongNumber: out_of_range: 0x10000000000000000"); ASSERT_THROW_EQUALS(MathLib::toBigNumber("0x10000000000000000"), InternalError, "Internal Error. MathLib::toBigNumber: out_of_range: 0x10000000000000000");
ASSERT_THROW_EQUALS(MathLib::toLongNumber("-0x10000000000000000"), InternalError, "Internal Error. MathLib::toLongNumber: out_of_range: -0x10000000000000000"); ASSERT_THROW_EQUALS(MathLib::toBigNumber("-0x10000000000000000"), InternalError, "Internal Error. MathLib::toBigNumber: out_of_range: -0x10000000000000000");
// min/max and out-of-bounds - octal // min/max and out-of-bounds - octal
{ {
const MathLib::bigint i = 01777777777777777777777; const MathLib::bigint i = 01777777777777777777777;
ASSERT_EQUALS(i, MathLib::toLongNumber(std::to_string(i))); ASSERT_EQUALS(i, MathLib::toBigNumber(std::to_string(i)));
ASSERT_EQUALS(i, MathLib::toLongNumber("01777777777777777777777")); ASSERT_EQUALS(i, MathLib::toBigNumber("01777777777777777777777"));
} }
{ {
const MathLib::bigint i = -01777777777777777777777; const MathLib::bigint i = -01777777777777777777777;
ASSERT_EQUALS(i, MathLib::toLongNumber(std::to_string(i))); ASSERT_EQUALS(i, MathLib::toBigNumber(std::to_string(i)));
ASSERT_EQUALS(i, MathLib::toLongNumber("-01777777777777777777777")); ASSERT_EQUALS(i, MathLib::toBigNumber("-01777777777777777777777"));
} }
ASSERT_THROW_EQUALS(MathLib::toLongNumber("02000000000000000000000"), InternalError, "Internal Error. MathLib::toLongNumber: out_of_range: 02000000000000000000000"); ASSERT_THROW_EQUALS(MathLib::toBigNumber("02000000000000000000000"), InternalError, "Internal Error. MathLib::toBigNumber: out_of_range: 02000000000000000000000");
ASSERT_THROW_EQUALS(MathLib::toLongNumber("-02000000000000000000000"), InternalError, "Internal Error. MathLib::toLongNumber: out_of_range: -02000000000000000000000"); ASSERT_THROW_EQUALS(MathLib::toBigNumber("-02000000000000000000000"), InternalError, "Internal Error. MathLib::toBigNumber: out_of_range: -02000000000000000000000");
// min/max and out-of-bounds - decimal // min/max and out-of-bounds - decimal
SUPPRESS_WARNING_CLANG_PUSH("-Wimplicitly-unsigned-literal") SUPPRESS_WARNING_CLANG_PUSH("-Wimplicitly-unsigned-literal")
SUPPRESS_WARNING_GCC_PUSH("-Woverflow") SUPPRESS_WARNING_GCC_PUSH("-Woverflow")
{ {
const MathLib::bigint i = 18446744073709551615; const MathLib::bigint i = 18446744073709551615;
ASSERT_EQUALS(i, MathLib::toLongNumber(std::to_string(i))); ASSERT_EQUALS(i, MathLib::toBigNumber(std::to_string(i)));
ASSERT_EQUALS(i, MathLib::toLongNumber("18446744073709551615")); ASSERT_EQUALS(i, MathLib::toBigNumber("18446744073709551615"));
} }
{ {
const MathLib::bigint i = -18446744073709551615; const MathLib::bigint i = -18446744073709551615;
ASSERT_EQUALS(i, MathLib::toLongNumber(std::to_string(i))); ASSERT_EQUALS(i, MathLib::toBigNumber(std::to_string(i)));
ASSERT_EQUALS(i, MathLib::toLongNumber("-18446744073709551615")); ASSERT_EQUALS(i, MathLib::toBigNumber("-18446744073709551615"));
} }
SUPPRESS_WARNING_GCC_POP SUPPRESS_WARNING_GCC_POP
SUPPRESS_WARNING_CLANG_POP SUPPRESS_WARNING_CLANG_POP
ASSERT_THROW_EQUALS(MathLib::toLongNumber("18446744073709551616"), InternalError, "Internal Error. MathLib::toLongNumber: out_of_range: 18446744073709551616"); ASSERT_THROW_EQUALS(MathLib::toBigNumber("18446744073709551616"), InternalError, "Internal Error. MathLib::toBigNumber: out_of_range: 18446744073709551616");
ASSERT_THROW_EQUALS(MathLib::toLongNumber("-18446744073709551616"), InternalError, "Internal Error. MathLib::toLongNumber: out_of_range: -18446744073709551616"); ASSERT_THROW_EQUALS(MathLib::toBigNumber("-18446744073709551616"), InternalError, "Internal Error. MathLib::toBigNumber: out_of_range: -18446744073709551616");
ASSERT_THROW_EQUALS(MathLib::toLongNumber("invalid"), InternalError, "Internal Error. MathLib::toLongNumber: invalid_argument: invalid"); ASSERT_THROW_EQUALS(MathLib::toBigNumber("invalid"), InternalError, "Internal Error. MathLib::toBigNumber: invalid_argument: invalid");
ASSERT_THROW_EQUALS(MathLib::toLongNumber("1invalid"), InternalError, "Internal Error. MathLib::toLongNumber: input was not completely consumed: 1invalid"); ASSERT_THROW_EQUALS(MathLib::toBigNumber("1invalid"), InternalError, "Internal Error. MathLib::toBigNumber: 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"); ASSERT_THROW_EQUALS(MathLib::toBigNumber("1 invalid"), InternalError, "Internal Error. MathLib::toBigNumber: input was not completely consumed: 1 invalid");
// TODO: test binary // TODO: test binary
// TODO: test floating point // TODO: test floating point
@ -411,160 +415,164 @@ private:
// TODO: test with 128-bit values // TODO: test with 128-bit values
} }
void toULongNumber() const { void toBigUNumber() const {
// zero input // zero input
ASSERT_EQUALS(0, MathLib::toULongNumber("0")); ASSERT_EQUALS(0, MathLib::toBigUNumber("0"));
ASSERT_EQUALS(0, MathLib::toULongNumber("-0")); ASSERT_EQUALS(0, MathLib::toBigUNumber("-0"));
ASSERT_EQUALS(0, MathLib::toULongNumber("+0")); ASSERT_EQUALS(0, MathLib::toBigUNumber("+0"));
ASSERT_EQUALS(0, MathLib::toULongNumber("0L")); ASSERT_EQUALS(0, MathLib::toBigUNumber("0L"));
ASSERT_EQUALS(0, MathLib::toULongNumber("0l")); ASSERT_EQUALS(0, MathLib::toBigUNumber("0l"));
ASSERT_EQUALS(0, MathLib::toULongNumber("0LL")); ASSERT_EQUALS(0, MathLib::toBigUNumber("0LL"));
ASSERT_EQUALS(0, MathLib::toULongNumber("0ll")); ASSERT_EQUALS(0, MathLib::toBigUNumber("0ll"));
ASSERT_EQUALS(0, MathLib::toULongNumber("0U")); ASSERT_EQUALS(0, MathLib::toBigUNumber("0U"));
ASSERT_EQUALS(0, MathLib::toULongNumber("0u")); ASSERT_EQUALS(0, MathLib::toBigUNumber("0u"));
ASSERT_EQUALS(0, MathLib::toULongNumber("0UL")); ASSERT_EQUALS(0, MathLib::toBigUNumber("0UL"));
ASSERT_EQUALS(0, MathLib::toULongNumber("0ul")); ASSERT_EQUALS(0, MathLib::toBigUNumber("0ul"));
ASSERT_EQUALS(0, MathLib::toULongNumber("0ULL")); ASSERT_EQUALS(0, MathLib::toBigUNumber("0ULL"));
ASSERT_EQUALS(0, MathLib::toULongNumber("0ull")); ASSERT_EQUALS(0, MathLib::toBigUNumber("0ull"));
ASSERT_EQUALS(0, MathLib::toULongNumber("0i64")); // Visual Studio-specific ASSERT_EQUALS(0, MathLib::toBigUNumber("0i64")); // Visual Studio-specific
ASSERT_EQUALS(0, MathLib::toULongNumber("0ui64")); // Visual Studio-specific ASSERT_EQUALS(0, MathLib::toBigUNumber("0ui64")); // Visual Studio-specific
// TODO: needs to fail // TODO: needs to fail
//ASSERT_EQUALS(0, MathLib::toULongNumber("0lll")); //ASSERT_EQUALS(0, MathLib::toBigUNumber("0lll"));
//ASSERT_EQUALS(0, MathLib::toULongNumber("0uu")); //ASSERT_EQUALS(0, MathLib::toBigUNumber("0uu"));
ASSERT_EQUALS(1U, MathLib::toULongNumber("1U")); ASSERT_EQUALS(1U, MathLib::toBigUNumber("1U"));
ASSERT_EQUALS(10000U, MathLib::toULongNumber("1e4")); ASSERT_EQUALS(10000U, MathLib::toBigUNumber("1e4"));
ASSERT_EQUALS(10000U, MathLib::toULongNumber("1e4")); ASSERT_EQUALS(10000U, MathLib::toBigUNumber("1e4"));
ASSERT_EQUALS(0xFF00000000000000UL, MathLib::toULongNumber("0xFF00000000000000UL")); ASSERT_EQUALS(0xFF00000000000000UL, MathLib::toBigUNumber("0xFF00000000000000UL"));
ASSERT_EQUALS(0x0A00000000000000UL, MathLib::toULongNumber("0x0A00000000000000UL")); ASSERT_EQUALS(0x0A00000000000000UL, MathLib::toBigUNumber("0x0A00000000000000UL"));
// from hex // from hex
ASSERT_EQUALS(0, MathLib::toULongNumber("0x0")); ASSERT_EQUALS(0, MathLib::toBigUNumber("0x0"));
ASSERT_EQUALS(0, MathLib::toULongNumber("-0x0")); ASSERT_EQUALS(0, MathLib::toBigUNumber("-0x0"));
ASSERT_EQUALS(0, MathLib::toULongNumber("+0x0")); ASSERT_EQUALS(0, MathLib::toBigUNumber("+0x0"));
ASSERT_EQUALS(10, MathLib::toULongNumber("0xa")); ASSERT_EQUALS(10, MathLib::toBigUNumber("0xa"));
ASSERT_EQUALS(10995, MathLib::toULongNumber("0x2AF3")); ASSERT_EQUALS(10995, MathLib::toBigUNumber("0x2AF3"));
ASSERT_EQUALS(-10, MathLib::toULongNumber("-0xa")); ASSERT_EQUALS(-10, MathLib::toBigUNumber("-0xa"));
ASSERT_EQUALS(-10995, MathLib::toULongNumber("-0x2AF3")); ASSERT_EQUALS(-10995, MathLib::toBigUNumber("-0x2AF3"));
ASSERT_EQUALS(10, MathLib::toULongNumber("+0xa")); ASSERT_EQUALS(10, MathLib::toBigUNumber("+0xa"));
ASSERT_EQUALS(10995, MathLib::toULongNumber("+0x2AF3")); ASSERT_EQUALS(10995, MathLib::toBigUNumber("+0x2AF3"));
// from octal // from octal
ASSERT_EQUALS(8, MathLib::toULongNumber("010")); ASSERT_EQUALS(8, MathLib::toBigUNumber("010"));
ASSERT_EQUALS(8, MathLib::toULongNumber("+010")); ASSERT_EQUALS(8, MathLib::toBigUNumber("+010"));
ASSERT_EQUALS(-8, MathLib::toULongNumber("-010")); ASSERT_EQUALS(-8, MathLib::toBigUNumber("-010"));
ASSERT_EQUALS(125, MathLib::toULongNumber("0175")); ASSERT_EQUALS(125, MathLib::toBigUNumber("0175"));
ASSERT_EQUALS(125, MathLib::toULongNumber("+0175")); ASSERT_EQUALS(125, MathLib::toBigUNumber("+0175"));
ASSERT_EQUALS(-125, MathLib::toULongNumber("-0175")); ASSERT_EQUALS(-125, MathLib::toBigUNumber("-0175"));
// from binary // from binary
ASSERT_EQUALS(0, MathLib::toULongNumber("0b0")); ASSERT_EQUALS(0, MathLib::toBigUNumber("0b0"));
ASSERT_EQUALS(1, MathLib::toULongNumber("0b1")); ASSERT_EQUALS(1, MathLib::toBigUNumber("0b1"));
ASSERT_EQUALS(1, MathLib::toULongNumber("0b1U")); ASSERT_EQUALS(1, MathLib::toBigUNumber("0b1U"));
ASSERT_EQUALS(1, MathLib::toULongNumber("0b1L")); ASSERT_EQUALS(1, MathLib::toBigUNumber("0b1L"));
ASSERT_EQUALS(1, MathLib::toULongNumber("0b1LU")); ASSERT_EQUALS(1, MathLib::toBigUNumber("0b1LU"));
ASSERT_EQUALS(1, MathLib::toULongNumber("0b1LL")); ASSERT_EQUALS(1, MathLib::toBigUNumber("0b1LL"));
ASSERT_EQUALS(1, MathLib::toULongNumber("0b1LLU")); ASSERT_EQUALS(1, MathLib::toBigUNumber("0b1LLU"));
ASSERT_EQUALS(1, MathLib::toULongNumber("+0b1")); ASSERT_EQUALS(1, MathLib::toBigUNumber("+0b1"));
ASSERT_EQUALS(-1, MathLib::toULongNumber("-0b1")); ASSERT_EQUALS(-1, MathLib::toBigUNumber("-0b1"));
ASSERT_EQUALS(9U, MathLib::toULongNumber("011")); ASSERT_EQUALS(9U, MathLib::toBigUNumber("011"));
ASSERT_EQUALS(5U, MathLib::toULongNumber("0b101")); ASSERT_EQUALS(5U, MathLib::toBigUNumber("0b101"));
ASSERT_EQUALS(215, MathLib::toULongNumber("0b11010111")); ASSERT_EQUALS(215, MathLib::toBigUNumber("0b11010111"));
ASSERT_EQUALS(-215, MathLib::toULongNumber("-0b11010111")); ASSERT_EQUALS(-215, MathLib::toBigUNumber("-0b11010111"));
ASSERT_EQUALS(215, MathLib::toULongNumber("0B11010111")); ASSERT_EQUALS(215, MathLib::toBigUNumber("0B11010111"));
// from base 10 // from base 10
ASSERT_EQUALS(10, MathLib::toULongNumber("10")); ASSERT_EQUALS(10, MathLib::toBigUNumber("10"));
ASSERT_EQUALS(10, MathLib::toULongNumber("10.")); ASSERT_EQUALS(10, MathLib::toBigUNumber("10."));
ASSERT_EQUALS(10, MathLib::toULongNumber("10.0")); ASSERT_EQUALS(10, MathLib::toBigUNumber("10.0"));
ASSERT_EQUALS(100, MathLib::toULongNumber("10E+1")); ASSERT_EQUALS(100, MathLib::toBigUNumber("10E+1"));
ASSERT_EQUALS(1, MathLib::toULongNumber("10E-1")); ASSERT_EQUALS(1, MathLib::toBigUNumber("10E-1"));
ASSERT_EQUALS(100, MathLib::toULongNumber("+10E+1")); ASSERT_EQUALS(100, MathLib::toBigUNumber("+10E+1"));
ASSERT_EQUALS(-1, MathLib::toULongNumber("-10E-1")); ASSERT_EQUALS(-1, MathLib::toBigUNumber("-10E-1"));
ASSERT_EQUALS(100, MathLib::toULongNumber("+10.E+1")); ASSERT_EQUALS(100, MathLib::toBigUNumber("+10.E+1"));
ASSERT_EQUALS(-1, MathLib::toULongNumber("-10.E-1")); ASSERT_EQUALS(-1, MathLib::toBigUNumber("-10.E-1"));
ASSERT_EQUALS(100, MathLib::toULongNumber("+10.0E+1")); ASSERT_EQUALS(100, MathLib::toBigUNumber("+10.0E+1"));
ASSERT_EQUALS(-1, MathLib::toULongNumber("-10.0E-1")); ASSERT_EQUALS(-1, MathLib::toBigUNumber("-10.0E-1"));
// from char // from char
ASSERT_EQUALS((int)('A'), MathLib::toULongNumber("'A'")); ASSERT_EQUALS((int)('A'), MathLib::toBigUNumber("'A'"));
ASSERT_EQUALS((int)('\x10'), MathLib::toULongNumber("'\\x10'")); ASSERT_EQUALS((int)('\x10'), MathLib::toBigUNumber("'\\x10'"));
ASSERT_EQUALS((int)('\100'), MathLib::toULongNumber("'\\100'")); ASSERT_EQUALS((int)('\100'), MathLib::toBigUNumber("'\\100'"));
ASSERT_EQUALS((int)('\200'), MathLib::toULongNumber("'\\200'")); ASSERT_EQUALS((int)('\200'), MathLib::toBigUNumber("'\\200'"));
ASSERT_EQUALS((int)(L'A'), MathLib::toULongNumber("L'A'")); ASSERT_EQUALS((int)(L'A'), MathLib::toBigUNumber("L'A'"));
ASSERT_EQUALS(9894494448401390090ULL, MathLib::toULongNumber("0x89504e470d0a1a0a")); ASSERT_EQUALS(9894494448401390090ULL, MathLib::toBigUNumber("0x89504e470d0a1a0a"));
ASSERT_EQUALS(9965707617509186058ULL, MathLib::toULongNumber("0x8a4d4e470d0a1a0a")); ASSERT_EQUALS(9965707617509186058ULL, MathLib::toBigUNumber("0x8a4d4e470d0a1a0a"));
// from long long // from long long
/* /*
* ASSERT_EQUALS(0xFF00000000000000LL, MathLib::toULongNumber("0xFF00000000000000LL")); * ASSERT_EQUALS(0xFF00000000000000LL, MathLib::toBigUNumber("0xFF00000000000000LL"));
* This does not work in a portable way! * 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) * 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")); ASSERT_EQUALS(0x0A00000000000000LL, MathLib::toBigUNumber("0x0A00000000000000LL"));
// min/max numeric limits // 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>::min(),
ASSERT_EQUALS(std::numeric_limits<long long>::max(), MathLib::toULongNumber(std::to_string(std::numeric_limits<long long>::max()))); MathLib::toBigUNumber(std::to_string(std::numeric_limits<long long>::min())));
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<long long>::max(),
ASSERT_EQUALS(std::numeric_limits<unsigned long long>::max(), MathLib::toULongNumber(std::to_string(std::numeric_limits<unsigned long long>::max()))); MathLib::toBigUNumber(std::to_string(std::numeric_limits<long long>::max())));
ASSERT_EQUALS(std::numeric_limits<unsigned long long>::min(),
MathLib::toBigUNumber(std::to_string(std::numeric_limits<unsigned long long>::min())));
ASSERT_EQUALS(std::numeric_limits<unsigned long long>::max(),
MathLib::toBigUNumber(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::biguint u = 0xFFFFFFFFFFFFFFFF; const MathLib::biguint u = 0xFFFFFFFFFFFFFFFF;
ASSERT_EQUALS(u, MathLib::toULongNumber(std::to_string(u))); ASSERT_EQUALS(u, MathLib::toBigUNumber(std::to_string(u)));
ASSERT_EQUALS(u, MathLib::toULongNumber("0xFFFFFFFFFFFFFFFF")); ASSERT_EQUALS(u, MathLib::toBigUNumber("0xFFFFFFFFFFFFFFFF"));
} }
{ {
const MathLib::biguint u = -0xFFFFFFFFFFFFFFFF; const MathLib::biguint u = -0xFFFFFFFFFFFFFFFF;
ASSERT_EQUALS(u, MathLib::toULongNumber(std::to_string(u))); ASSERT_EQUALS(u, MathLib::toBigUNumber(std::to_string(u)));
ASSERT_EQUALS(u, MathLib::toULongNumber("-0xFFFFFFFFFFFFFFFF")); ASSERT_EQUALS(u, MathLib::toBigUNumber("-0xFFFFFFFFFFFFFFFF"));
} }
ASSERT_THROW_EQUALS(MathLib::toULongNumber("0x10000000000000000"), InternalError, "Internal Error. MathLib::toULongNumber: out_of_range: 0x10000000000000000"); ASSERT_THROW_EQUALS(MathLib::toBigUNumber("0x10000000000000000"), InternalError, "Internal Error. MathLib::toBigUNumber: out_of_range: 0x10000000000000000");
ASSERT_THROW_EQUALS(MathLib::toULongNumber("-0x10000000000000000"), InternalError, "Internal Error. MathLib::toULongNumber: out_of_range: -0x10000000000000000"); ASSERT_THROW_EQUALS(MathLib::toBigUNumber("-0x10000000000000000"), InternalError, "Internal Error. MathLib::toBigUNumber: out_of_range: -0x10000000000000000");
// min/max and out-of-bounds - octal // min/max and out-of-bounds - octal
{ {
const MathLib::biguint u = 01777777777777777777777; const MathLib::biguint u = 01777777777777777777777;
ASSERT_EQUALS(u, MathLib::toULongNumber(std::to_string(u))); ASSERT_EQUALS(u, MathLib::toBigUNumber(std::to_string(u)));
ASSERT_EQUALS(u, MathLib::toULongNumber("01777777777777777777777")); ASSERT_EQUALS(u, MathLib::toBigUNumber("01777777777777777777777"));
} }
{ {
const MathLib::biguint u = -01777777777777777777777; const MathLib::biguint u = -01777777777777777777777;
ASSERT_EQUALS(u, MathLib::toULongNumber(std::to_string(u))); ASSERT_EQUALS(u, MathLib::toBigUNumber(std::to_string(u)));
ASSERT_EQUALS(u, MathLib::toULongNumber("-01777777777777777777777")); ASSERT_EQUALS(u, MathLib::toBigUNumber("-01777777777777777777777"));
} }
ASSERT_THROW_EQUALS(MathLib::toULongNumber("02000000000000000000000"), InternalError, "Internal Error. MathLib::toULongNumber: out_of_range: 02000000000000000000000"); ASSERT_THROW_EQUALS(MathLib::toBigUNumber("02000000000000000000000"), InternalError, "Internal Error. MathLib::toBigUNumber: out_of_range: 02000000000000000000000");
ASSERT_THROW_EQUALS(MathLib::toULongNumber("-02000000000000000000000"), InternalError, "Internal Error. MathLib::toULongNumber: out_of_range: -02000000000000000000000"); ASSERT_THROW_EQUALS(MathLib::toBigUNumber("-02000000000000000000000"), InternalError, "Internal Error. MathLib::toBigUNumber: out_of_range: -02000000000000000000000");
// min/max and out-of-bounds - decimal // min/max and out-of-bounds - decimal
SUPPRESS_WARNING_CLANG_PUSH("-Wimplicitly-unsigned-literal") SUPPRESS_WARNING_CLANG_PUSH("-Wimplicitly-unsigned-literal")
SUPPRESS_WARNING_GCC_PUSH("-Woverflow") SUPPRESS_WARNING_GCC_PUSH("-Woverflow")
{ {
const MathLib::biguint u = 18446744073709551615; const MathLib::biguint u = 18446744073709551615;
ASSERT_EQUALS(u, MathLib::toULongNumber(std::to_string(u))); ASSERT_EQUALS(u, MathLib::toBigUNumber(std::to_string(u)));
ASSERT_EQUALS(u, MathLib::toULongNumber("18446744073709551615")); ASSERT_EQUALS(u, MathLib::toBigUNumber("18446744073709551615"));
} }
{ {
const MathLib::biguint u = -18446744073709551615; const MathLib::biguint u = -18446744073709551615;
ASSERT_EQUALS(u, MathLib::toULongNumber(std::to_string(u))); ASSERT_EQUALS(u, MathLib::toBigUNumber(std::to_string(u)));
ASSERT_EQUALS(u, MathLib::toULongNumber("-18446744073709551615")); ASSERT_EQUALS(u, MathLib::toBigUNumber("-18446744073709551615"));
} }
SUPPRESS_WARNING_GCC_POP SUPPRESS_WARNING_GCC_POP
SUPPRESS_WARNING_CLANG_POP SUPPRESS_WARNING_CLANG_POP
ASSERT_THROW_EQUALS(MathLib::toULongNumber("18446744073709551616"), InternalError, "Internal Error. MathLib::toULongNumber: out_of_range: 18446744073709551616"); ASSERT_THROW_EQUALS(MathLib::toBigUNumber("18446744073709551616"), InternalError, "Internal Error. MathLib::toBigUNumber: out_of_range: 18446744073709551616");
ASSERT_THROW_EQUALS(MathLib::toULongNumber("-18446744073709551616"), InternalError, "Internal Error. MathLib::toULongNumber: out_of_range: -18446744073709551616"); ASSERT_THROW_EQUALS(MathLib::toBigUNumber("-18446744073709551616"), InternalError, "Internal Error. MathLib::toBigUNumber: out_of_range: -18446744073709551616");
ASSERT_THROW_EQUALS(MathLib::toULongNumber("invalid"), InternalError, "Internal Error. MathLib::toULongNumber: invalid_argument: invalid"); ASSERT_THROW_EQUALS(MathLib::toBigUNumber("invalid"), InternalError, "Internal Error. MathLib::toBigUNumber: invalid_argument: invalid");
ASSERT_THROW_EQUALS(MathLib::toULongNumber("1invalid"), InternalError, "Internal Error. MathLib::toULongNumber: input was not completely consumed: 1invalid"); ASSERT_THROW_EQUALS(MathLib::toBigUNumber("1invalid"), InternalError, "Internal Error. MathLib::toBigUNumber: 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"); ASSERT_THROW_EQUALS(MathLib::toBigUNumber("1 invalid"), InternalError, "Internal Error. MathLib::toBigUNumber: input was not completely consumed: 1 invalid");
// TODO: test binary // TODO: test binary
// TODO: test floating point // TODO: test floating point