File 2002-floating-point-numbers.patch of Package kcalc
diff --git a/autotests/kcalc_parser_core_test.cpp b/autotests/kcalc_parser_core_test.cpp
index 23a75543057afc2890b1fc6448ae7d41ca9c57c9..b2a56f85215a8faaf2ee761ef5f70f55590738fd 100644
--- a/autotests/kcalc_parser_core_test.cpp
+++ b/autotests/kcalc_parser_core_test.cpp
@@ -83,7 +83,7 @@ void KCalcParserCoreTest::testParserCore_data()
QTest::newRow("inverse test 1") << QS("10⁻¹") << 10 << QS("1/10");
QTest::newRow("inverse test 2") << QS("10⁻¹⁻¹") << 10 << QS("10");
- QTest::newRow("sqrt test 2") << QS("√5") << 10 << QS("2.2360679775");
+ QTest::newRow("sqrt test 1") << QS("√5") << 10 << QS("2.2360679775");
QTest::newRow("sqrt test 2") << QS("∛5") << 10 << QS("1.70997594668");
QTest::newRow("square test 1") << QS("2.2360679775²") << 10 << QS("5");
QTest::newRow("square test 2") << QS("2.2360679775²²") << 10 << QS("25");
@@ -93,8 +93,8 @@ void KCalcParserCoreTest::testParserCore_data()
QTest::newRow("sin test2") << QS("sin(45)") << 10 << QS("0.707106781187");
QTest::newRow("cos test") << QS("cos(90)") << 10 << QS("0");
QTest::newRow("tan test") << QS("tan(45)") << 10 << QS("1");
- QTest::newRow("asin test") << QS("asin(0.707106781187)") << 10 << QS("45");
- QTest::newRow("asin test") << QS("asin(1)") << 10 << QS("90");
+ QTest::newRow("asin test 1") << QS("asin(0.707106781187)") << 10 << QS("45");
+ QTest::newRow("asin test 2") << QS("asin(1)") << 10 << QS("90");
QTest::newRow("acos test") << QS("acos(0)") << 10 << QS("90");
QTest::newRow("atan test") << QS("atan(1)") << 10 << QS("45");
@@ -174,10 +174,10 @@ void KCalcParserCoreTest::testParserCore_data()
QTest::newRow("base test 2") << QS("0xFF & 0b1111 & 0o7") << 2 << QS("7");
QTest::newRow("base test 3") << QS("0xFF & 0b1111 & 0o7") << 8 << QS("7");
QTest::newRow("base test 4") << QS("0xFF & 0b1111 & 0o7") << 16 << QS("7");
- QTest::newRow("base test 5") << QS("010+10") << 2 << QS("4");
- QTest::newRow("base test 6") << QS("010+10") << 16 << QS("32");
+ QTest::newRow("base test 5") << QS("010+10") << 2 << QS("10");
+ QTest::newRow("base test 6") << QS("010+10") << 16 << QS("24");
QTest::newRow("base test 7") << QS("010+10") << 8 << QS("16");
- QTest::newRow("base test 8") << QS("010+10") << 10 << QS("20");
+ QTest::newRow("base test 8") << QS("010+10") << 10 << QS("18");
// parenthesis input
QTest::newRow("parenthesis test 1") << QS("(√5)²") << 10 << QS("5");
QTest::newRow("parenthesis test 2") << QS("(1+3)") << 10 << QS("4");
@@ -269,7 +269,6 @@ void KCalcParserCoreTest::testParserCoreNumeralSystem()
QFETCH(int, base);
QFETCH(QString, expectedResult);
- parser.setNumeralMode(true);
KCalcParser::ParsingResult parsing_result;
int calculation_result, errorIndex;
parsing_result = parser.stringToTokenQueue(input, base, token_Queue_, errorIndex);
@@ -283,8 +282,6 @@ void KCalcParserCoreTest::testParserCoreNumeralSystem()
coreResult.replace(KNumber::decimalSeparator().at(0), QLatin1Char('.'));
coreResult.replace(QLatin1Char(','), QLatin1Char('.'));
QCOMPARE(coreResult, expectedResult);
-
- parser.setNumeralMode(false);
}
void KCalcParserCoreTest::testParserError_data()
diff --git a/kcalc.cpp b/kcalc.cpp
index 1237a48031a6ae1a63a8969437a9df0f8824b059..43d5bef827bddb95b3c578fb22ba5e0899a0d953 100644
--- a/kcalc.cpp
+++ b/kcalc.cpp
@@ -790,9 +790,6 @@ void KCalculator::slotBaseSelected()
(num_button_group_->buttons().at(i))->setEnabled(false);
}
- // Only enable the decimal point in decimal
- pbPeriod->setEnabled(current_base == NB_DECIMAL);
-
// Only enable the x*10^y button in decimal
pbEE->setEnabled(current_base == NB_DECIMAL);
@@ -1810,8 +1807,6 @@ void KCalculator::slotSetSimpleMode()
{
bool wasMinimumSize = isMinimumSize();
- this->parser.setNumeralMode(false);
-
action_constants_show_->setChecked(false);
action_constants_show_->setEnabled(false);
action_bitset_show_->setEnabled(false);
@@ -1868,8 +1863,6 @@ void KCalculator::slotSetScienceMode()
{
bool wasMinimumSize = isMinimumSize();
- this->parser.setNumeralMode(false);
-
action_constants_show_->setEnabled(true);
action_constants_show_->setChecked(KCalcSettings::showConstants());
action_bitset_show_->setEnabled(false);
@@ -1926,8 +1919,6 @@ void KCalculator::slotSetStatisticMode()
{
bool wasMinimumSize = isMinimumSize();
- this->parser.setNumeralMode(false);
-
action_constants_show_->setEnabled(true);
action_constants_show_->setChecked(KCalcSettings::showConstants());
action_bitset_show_->setEnabled(false);
@@ -1984,8 +1975,6 @@ void KCalculator::slotSetNumeralMode()
{
bool wasMinimumSize = isMinimumSize();
- this->parser.setNumeralMode(true);
-
action_constants_show_->setChecked(false);
action_constants_show_->setEnabled(false);
action_bitset_show_->setEnabled(true);
diff --git a/kcalc_display.cpp b/kcalc_display.cpp
index 98105d20006f8904ef6c9b983fe2f74d00c74f47..46d50518708bfc6700ab2a7df8b9961a0b7a459a 100644
--- a/kcalc_display.cpp
+++ b/kcalc_display.cpp
@@ -478,30 +478,13 @@ bool KCalcDisplay::setAmount(const KNumber &new_amount)
{
QString display_str;
- if ((num_base_ != NB_DECIMAL) && (new_amount.type() != KNumber::TYPE_ERROR)) {
+ if (twoscomplement_ && num_base_ != NB_DECIMAL && new_amount.type() != KNumber::TYPE_ERROR) {
+ // treat number as 64-bit unsigned
display_amount_ = new_amount.integerPart();
-
- if (twoscomplement_) {
- // treat number as 64-bit unsigned
- const quint64 tmp_workaround = display_amount_.toUint64();
- display_str = QString::number(tmp_workaround, num_base_).toUpper();
- } else {
- // QString::number treats non-decimal as unsigned
- qint64 tmp_workaround = display_amount_.toInt64();
- const bool neg = tmp_workaround < 0;
- if (neg) {
- tmp_workaround = qAbs(tmp_workaround);
- }
-
- display_str = QString::number(tmp_workaround, num_base_).toUpper();
- if (neg) {
- display_str.prepend(QLocale().negativeSign());
- }
- }
+ display_str = QString::number(display_amount_.toUint64(), num_base_).toUpper();
} else {
- // num_base_ == NB_DECIMAL || new_amount.type() == KNumber::TYPE_ERROR
display_amount_ = new_amount;
- display_str = display_amount_.toQString(KCalcSettings::precision(), fixed_precision_);
+ display_str = display_amount_.toStringInBase(num_base_, KCalcSettings::precision(), fixed_precision_);
}
setText(display_str);
@@ -669,18 +652,24 @@ QString KCalcDisplay::formatDecimalNumber(QString string)
//------------------------------------------------------------------------------
QString KCalcDisplay::groupDigits(const QString &displayString, int numDigits)
{
- QString tmpDisplayString;
- const int stringLength = displayString.length();
+ const QString decimalPoint = locale().decimalPoint();
+ QString resultString = QString(displayString).replace(u'.', decimalPoint);
- for (int i = stringLength; i > 0; i--) {
- if (i % numDigits == 0 && i != stringLength) {
- tmpDisplayString = tmpDisplayString + QLatin1Char(' ');
+ if (groupdigits_ && !(locale().numberOptions() & QLocale::OmitGroupSeparator)) {
+ int pos = resultString.indexOf(decimalPoint);
+ if (pos == -1) {
+ pos = resultString.length();
}
- tmpDisplayString = tmpDisplayString + displayString[stringLength - i];
+ const QString groupSeparator = locale().groupSeparator();
+ for (int i = pos - 1; i > 0; i--) {
+ if ((pos - i) % numDigits == 0) {
+ resultString.insert(i, groupSeparator);
+ }
+ }
}
- return tmpDisplayString;
+ return resultString;
}
//------------------------------------------------------------------------------
diff --git a/kcalc_parser.cpp b/kcalc_parser.cpp
index 7b68c46df3bffe45bfc4c4e4eec65f65b787eeeb..dcc7f03910ff7399b7473a30f95dab7b30264fe7 100644
--- a/kcalc_parser.cpp
+++ b/kcalc_parser.cpp
@@ -16,17 +16,15 @@
#include <QRegularExpressionMatch>
#include <QString>
-const QString KCalcParser::BINARY_DIGITS_PATTERN = QStringLiteral("[0-1]{1,}");
-const QString KCalcParser::OCTAL_DIGITS_PATTERN = QStringLiteral("[0-7]{1,}");
-const QString KCalcParser::HEX_DIGITS_PATTERN = QStringLiteral("[0-9A-Fa-f]{1,}");
-
-const QString KCalcParser::DECIMAL_NUMBER_PATTERN = QLatin1String("(0*)((\\d*)[.,]?\\d+([e|E]([+-]?\\d+))?)");
-
-const QRegularExpression KCalcParser::BINARY_NUMBER_DIGITS_REGEX = QRegularExpression(KCalcParser::BINARY_DIGITS_PATTERN);
-const QRegularExpression KCalcParser::OCTAL_NUMBER_DIGITS_REGEX = QRegularExpression(KCalcParser::OCTAL_DIGITS_PATTERN);
-const QRegularExpression KCalcParser::HEX_NUMBER_DIGITS_REGEX = QRegularExpression(KCalcParser::HEX_DIGITS_PATTERN);
+const QString KCalcParser::HEX_NUMBER_PATTERN = QLatin1String("(0*)(([0-9a-f]*)[.,]?[0-9a-f]+([pP@]([+-]?[0-9]+))?)");
+const QString KCalcParser::DECIMAL_NUMBER_PATTERN = QLatin1String("(0*)(([0-9]*)[.,]?[0-9]+([eE@]([+-]?[0-9]+))?)");
+const QString KCalcParser::OCTAL_NUMBER_PATTERN = QLatin1String("(0*)(([0-7]*)[.,]?[0-7]+([eE@]([+-]?[0-9]+))?)");
+const QString KCalcParser::BINARY_NUMBER_PATTERN = QLatin1String("(0*)(([01]*)[.,]?[01]+([pP@]([+-]?[0-9]+))?)");
+const QRegularExpression KCalcParser::HEX_NUMBER_REGEX = QRegularExpression(KCalcParser::HEX_NUMBER_PATTERN);
const QRegularExpression KCalcParser::DECIMAL_NUMBER_REGEX = QRegularExpression(KCalcParser::DECIMAL_NUMBER_PATTERN);
+const QRegularExpression KCalcParser::OCTAL_NUMBER_REGEX = QRegularExpression(KCalcParser::OCTAL_NUMBER_PATTERN);
+const QRegularExpression KCalcParser::BINARY_NUMBER_REGEX = QRegularExpression(KCalcParser::BINARY_NUMBER_PATTERN);
//------------------------------------------------------------------------------
// Name: KCalcParser
@@ -46,12 +44,11 @@ KCalcParser::~KCalcParser() = default;
// Name: stringToToken
// Desc: tries to find a valid token starting at index
//------------------------------------------------------------------------------
-KCalcToken::TokenCode KCalcParser::stringToToken(const QString &buffer, int &index, int base)
+KCalcToken::TokenCode KCalcParser::stringToToken(QStringView buffer, int &index, int base)
{
qCDebug(KCALC_LOG) << "Converting string to Token ";
- int maxTokenLength = (index + 5 > buffer.size()) ? buffer.size() - index : 5;
- QString s = buffer.sliced(index, maxTokenLength);
+ QStringView s = buffer.sliced(index);
// TODO: change this to be switch table on the first char
if (s.startsWith(SPACE_STR) || s.startsWith(THIN_SPACE_STR)) {
@@ -60,47 +57,48 @@ KCalcToken::TokenCode KCalcParser::stringToToken(const QString &buffer, int &ind
}
if (s.startsWith(HEX_NUMBER_PREFIX_STR)) {
+ const int from = HEX_NUMBER_PREFIX_STR.length();
QRegularExpressionMatch match;
- int numIndex = buffer.indexOf(HEX_NUMBER_DIGITS_REGEX, index + HEX_NUMBER_PREFIX_STR.length(), &match);
- if (numIndex == index + HEX_NUMBER_PREFIX_STR.length()) {
- token_KNumber_ = HEX_NUMBER_PREFIX_STR + match.captured();
- if (match.captured().size() > 16) {
- return KCalcToken::TokenCode::INVALID_TOKEN;
- }
- index += HEX_NUMBER_PREFIX_STR.length();
- index += match.captured().size();
+ if (s.indexOf(HEX_NUMBER_REGEX, from, &match) == from) {
+ token_KNumber_ = match.captured();
+ token_KNumber_base_ = 16;
+ index += match.capturedEnd();
return KCalcToken::TokenCode::KNUMBER;
- } else {
- return KCalcToken::TokenCode::INVALID_TOKEN;
}
+ return KCalcToken::TokenCode::INVALID_TOKEN;
}
if (s.startsWith(BINARY_NUMBER_PREFIX_STR)) {
+ const int from = BINARY_NUMBER_PREFIX_STR.length();
QRegularExpressionMatch match;
- int numIndex = buffer.indexOf(BINARY_NUMBER_DIGITS_REGEX, index + BINARY_NUMBER_PREFIX_STR.length(), &match);
- if (numIndex == index + BINARY_NUMBER_PREFIX_STR.length()) {
- token_KNumber_ = BINARY_NUMBER_PREFIX_STR + match.captured();
- if (match.captured().size() > 64) {
- return KCalcToken::TokenCode::INVALID_TOKEN;
- }
- index += BINARY_NUMBER_PREFIX_STR.length();
- index += match.captured().size();
+ if (s.indexOf(BINARY_NUMBER_REGEX, from, &match) == from) {
+ token_KNumber_ = match.captured();
+ token_KNumber_base_ = 2;
+ index += match.capturedEnd();
return KCalcToken::TokenCode::KNUMBER;
- } else {
- return KCalcToken::TokenCode::INVALID_TOKEN;
}
+ return KCalcToken::TokenCode::INVALID_TOKEN;
}
if (s.startsWith(OCTAL_NUMBER_PREFIX_STR)) {
+ const int from = OCTAL_NUMBER_PREFIX_STR.length();
+ QRegularExpressionMatch match;
+ if (s.indexOf(OCTAL_NUMBER_REGEX, from, &match) == from) {
+ token_KNumber_ = match.captured();
+ token_KNumber_base_ = 8;
+ index += match.capturedEnd();
+ return KCalcToken::TokenCode::KNUMBER;
+ }
+ return KCalcToken::TokenCode::INVALID_TOKEN;
+ }
+
+ if (s.startsWith(OCTAL_NUMBER_PREFIX_STR_C_STYLE) && s.length() >= 2 && s.at(1) >= ZERO_STR && s.at(1) <= SEVEN_STR) {
+ const int from = OCTAL_NUMBER_PREFIX_STR_C_STYLE.length();
QRegularExpressionMatch match;
- int numIndex = buffer.indexOf(OCTAL_NUMBER_DIGITS_REGEX, index + OCTAL_NUMBER_PREFIX_STR.length(), &match);
- if (numIndex == index + OCTAL_NUMBER_PREFIX_STR.length()) {
- token_KNumber_ = OCTAL_NUMBER_PREFIX_STR_C_STYLE + match.captured();
- if (match.captured().size() > 21) {
- return KCalcToken::TokenCode::INVALID_TOKEN;
- }
- index += OCTAL_NUMBER_PREFIX_STR.length();
- index += match.captured().size();
+ if (s.indexOf(OCTAL_NUMBER_REGEX, from, &match) == from) {
+ token_KNumber_ = match.captured();
+ token_KNumber_base_ = 8;
+ index += match.capturedEnd();
return KCalcToken::TokenCode::KNUMBER;
}
// Code execution continues, since an entry could
@@ -108,49 +106,33 @@ KCalcToken::TokenCode KCalcParser::stringToToken(const QString &buffer, int &ind
// being a number in base 10 or 16
}
- if ((A_STR <= s.first(1) && s.first(1) <= F_STR) || (ZERO_STR <= s.first(1) && s.first(1) <= NINE_STR)
- || (s.first(1) == COMMA_STR || s.first(1) == POINT_STR)) {
- int numIndex = -1;
+ const auto isNumberChar = [](const QChar c) {
+ return ((A_STR <= c && c <= F_STR) || (ZERO_STR <= c && c <= NINE_STR) || c == COMMA_STR || c == POINT_STR);
+ };
+
+ if (isNumberChar(s.at(0))) {
QRegularExpressionMatch match;
switch (base) {
case 2:
- numIndex = buffer.indexOf(BINARY_NUMBER_DIGITS_REGEX, index, &match);
- token_KNumber_ = BINARY_NUMBER_PREFIX_STR;
- if (match.captured().size() > 64) {
- return KCalcToken::TokenCode::INVALID_TOKEN;
- }
+ match = BINARY_NUMBER_REGEX.matchView(s);
break;
case 8:
- numIndex = buffer.indexOf(OCTAL_NUMBER_DIGITS_REGEX, index, &match);
- token_KNumber_ = OCTAL_NUMBER_PREFIX_STR_C_STYLE;
- if (match.captured().size() > 21) {
- return KCalcToken::TokenCode::INVALID_TOKEN;
- }
+ match = OCTAL_NUMBER_REGEX.matchView(s);
break;
case 10:
- numIndex = buffer.indexOf(DECIMAL_NUMBER_REGEX, index, &match);
- token_KNumber_.clear();
+ match = DECIMAL_NUMBER_REGEX.matchView(s);
break;
case 16:
- numIndex = buffer.indexOf(HEX_NUMBER_DIGITS_REGEX, index, &match);
- token_KNumber_ = HEX_NUMBER_PREFIX_STR;
- if (match.captured().size() > 16) {
- return KCalcToken::TokenCode::INVALID_TOKEN;
- }
+ match = HEX_NUMBER_REGEX.matchView(s);
break;
default:
break;
}
- if (numIndex == index) {
- if (base == 10) {
- token_KNumber_ += match.captured(2);
- } else {
- token_KNumber_ += match.captured();
- }
- index += match.captured().size();
+ if (match.hasMatch() && match.capturedStart() == 0) {
+ token_KNumber_ = match.captured();
+ token_KNumber_base_ = base;
+ index += match.capturedEnd();
return KCalcToken::TokenCode::KNUMBER;
- } else {
- return KCalcToken::TokenCode::INVALID_TOKEN;
}
}
@@ -439,13 +421,11 @@ KCalcToken::TokenCode KCalcParser::stringToToken(const QString &buffer, int &ind
return KCalcToken::TokenCode::LN;
}
- if (index + 2 <= buffer.size()) {
- s = buffer.sliced(index, 2);
- if (constantSymbolToValue_(s)) {
- index += 2;
- return KCalcToken::TokenCode::KNUMBER;
- }
+ if (s.length() >= 2 && constantSymbolToValue_(s.sliced(0, 2))) {
+ index += 2;
+ return KCalcToken::TokenCode::KNUMBER;
}
+
if (s.startsWith(ONE_S_COMP_STR)) {
index++;
return KCalcToken::TokenCode::ONE_S_COMPLEMENT;
@@ -459,22 +439,7 @@ KCalcToken::TokenCode KCalcParser::stringToToken(const QString &buffer, int &ind
return KCalcToken::TokenCode::DOUBLE_FACTORIAL;
}
- s = buffer.sliced(index, 1);
-
- if ((A_LOWER_CASE_STR <= s.first(1) && s.first(1) <= F_LOWER_CASE_STR)) {
- if (m_numeralMode && base == 16) {
- QRegularExpressionMatch match;
- int numIndex = buffer.indexOf(HEX_NUMBER_DIGITS_REGEX, index, &match);
- if (match.captured().size() > 16 || numIndex != index) {
- return KCalcToken::TokenCode::INVALID_TOKEN;
- }
- token_KNumber_ = HEX_NUMBER_PREFIX_STR + match.captured();
- index += match.captured().size();
- return KCalcToken::TokenCode::KNUMBER;
- }
- }
-
- if (constantSymbolToValue_(s)) {
+ if (constantSymbolToValue_(s.sliced(0, 1))) {
index++;
return KCalcToken::TokenCode::KNUMBER;
}
@@ -504,11 +469,11 @@ KCalcParser::ParsingResult KCalcParser::stringToTokenQueue(const QString &buffer
return ParsingResult::EMPTY;
}
+ const QString bufferLowerCase = buffer.toLower();
while (buffer_index < buffer_size) {
- tokenCode = KCalcToken::TokenCode::INVALID_TOKEN;
KNumber operand;
- tokenCode = stringToToken(buffer, buffer_index, base);
+ tokenCode = stringToToken(bufferLowerCase, buffer_index, base);
if (tokenCode == KCalcToken::TokenCode::INVALID_TOKEN) {
parsing_Result_ = INVALID_TOKEN;
@@ -524,7 +489,7 @@ KCalcParser::ParsingResult KCalcParser::stringToTokenQueue(const QString &buffer
qCDebug(KCALC_LOG) << "String KNumber converted: " << token_KNumber_;
token_KNumber_.replace(COMMA_STR, KNumber::decimalSeparator());
token_KNumber_.replace(POINT_STR, KNumber::decimalSeparator());
- operand = KNumber(token_KNumber_);
+ operand = KNumber(token_KNumber_, token_KNumber_base_);
tokenQueue.enqueue(KCalcToken(operand, buffer_index));
} else {
@@ -574,16 +539,6 @@ int KCalcParser::getTrigonometricMode()
return trigonometric_Mode_;
}
-void KCalcParser::setNumeralMode(bool numeralMode)
-{
- m_numeralMode = numeralMode;
-}
-
-bool KCalcParser::getNumeralMode() const
-{
- return m_numeralMode;
-}
-
//------------------------------------------------------------------------------
// Name: getParsingResult
// Desc:
@@ -840,7 +795,7 @@ int KCalcParser::loadConstants(const QDomDocument &doc)
// Desc: tries to find a given constant in the stored constants list, returns
// true if found, loads value in token_KNumber_
//------------------------------------------------------------------------------
-bool KCalcParser::constantSymbolToValue_(const QString &constantSymbol)
+bool KCalcParser::constantSymbolToValue_(QStringView constantSymbol)
{
QList<constant_>::const_iterator i;
for (i = constants_.constBegin(); i != constants_.constEnd(); ++i) {
diff --git a/kcalc_parser.h b/kcalc_parser.h
index daad3afb377e58f7c1e5594e48b3b5709391b2e5..065347a58ac8f1bec139eec50a70aa5282288e60 100644
--- a/kcalc_parser.h
+++ b/kcalc_parser.h
@@ -36,9 +36,6 @@ public:
void setTrigonometricMode(int mode);
int getTrigonometricMode();
- void setNumeralMode(bool numeralMode);
- bool getNumeralMode() const;
-
ParsingResult getParsingResult();
ParsingResult stringToTokenQueue(const QString &buffer, int base, QQueue<KCalcToken> &tokenQueue, int &errorIndex);
@@ -47,39 +44,37 @@ public:
const QString TokenToString(KCalcToken::TokenCode tokenCode);
private:
- KCalcToken::TokenCode stringToToken(const QString &string, int &index, int base = 10);
+ KCalcToken::TokenCode stringToToken(QStringView buffer, int &index, int base);
static const inline QString SPACE_STR = QStringLiteral(" ");
static const inline QString THIN_SPACE_STR = QStringLiteral(" ");
- static const inline QString ZERO_STR = QStringLiteral("0");
- static const inline QString NINE_STR = QStringLiteral("9");
+ static const inline QChar ZERO_STR = u'0';
+ static const inline QChar SEVEN_STR = u'7';
+ static const inline QChar NINE_STR = u'9';
static const inline QString DECIMAL_POINT_STR = QLocale().decimalPoint();
- static const inline QString COMMA_STR = QLatin1String(",");
- static const inline QString POINT_STR = QLatin1String(".");
+ static const inline QChar COMMA_STR = u',';
+ static const inline QChar POINT_STR = u'.';
- static const inline QString A_STR = QStringLiteral("A");
- static const inline QString F_STR = QStringLiteral("F");
- static const inline QString A_LOWER_CASE_STR = QStringLiteral("a");
- static const inline QString F_LOWER_CASE_STR = QStringLiteral("f");
- static const inline QString B_STR = QStringLiteral("b");
- static const inline QString X_STR = QStringLiteral("x");
+ static const inline QChar A_STR = u'a';
+ static const inline QChar F_STR = u'f';
+ static const inline QChar B_STR = u'b';
+ static const inline QChar X_STR = u'x';
static const inline QString BINARY_NUMBER_PREFIX_STR = QStringLiteral("0b");
static const inline QString OCTAL_NUMBER_PREFIX_STR = QStringLiteral("0o");
static const inline QString OCTAL_NUMBER_PREFIX_STR_C_STYLE = QStringLiteral("0");
static const inline QString HEX_NUMBER_PREFIX_STR = QStringLiteral("0x");
- static const QString BINARY_DIGITS_PATTERN;
- static const QString OCTAL_DIGITS_PATTERN;
- static const QString HEX_DIGITS_PATTERN;
-
- static const QRegularExpression BINARY_NUMBER_DIGITS_REGEX;
- static const QRegularExpression OCTAL_NUMBER_DIGITS_REGEX;
- static const QRegularExpression HEX_NUMBER_DIGITS_REGEX;
-
+ static const QString HEX_NUMBER_PATTERN;
static const QString DECIMAL_NUMBER_PATTERN;
+ static const QString OCTAL_NUMBER_PATTERN;
+ static const QString BINARY_NUMBER_PATTERN;
+
+ static const QRegularExpression HEX_NUMBER_REGEX;
static const QRegularExpression DECIMAL_NUMBER_REGEX;
+ static const QRegularExpression OCTAL_NUMBER_REGEX;
+ static const QRegularExpression BINARY_NUMBER_REGEX;
static const inline QString E_STR = QStringLiteral("e");
static const inline QString PI_STR = QStringLiteral("π");
@@ -170,11 +165,11 @@ private:
} constant_;
QList<constant_> constants_;
- bool constantSymbolToValue_(const QString &constantSymbol);
+ bool constantSymbolToValue_(QStringView constantSymbol);
QString token_KNumber_;
+ int token_KNumber_base_ = 10;
bool m_inputHasConstants = false;
int trigonometric_Mode_ = DEGREES;
- bool m_numeralMode = false;
ParsingResult parsing_Result_ = EMPTY;
};
diff --git a/knumber/knumber.cpp b/knumber/knumber.cpp
index 94043bccc83646734b70655ce7fa13d0cb8a1619..816e7d0d01dae786de38442d4dbef4bac122e2e3 100644
--- a/knumber/knumber.cpp
+++ b/knumber/knumber.cpp
@@ -114,6 +114,68 @@ void round(QString &str, int precision, const QString &decimalSeparator, int bas
}
}
}
+
+//------------------------------------------------------------------------------
+// Name: parseFractionFromFloat
+//------------------------------------------------------------------------------
+detail::knumber_fraction* parseFractionFromFloat(QStringView str, int base)
+{
+ static const QRegularExpression binNumRegex(R"(^([+-]?[01]+)(?:\.([01]+))?(?:([pPeE@])([+-]?[0-9]+))?$)"_L1);
+ static const QRegularExpression decNumRegex(R"(^([+-]?[0-9]+)(?:\.([0-9]+))?(?:([eE@])([+-]?[0-9]+))?$)"_L1);
+ static const QRegularExpression hexNumRegex(R"(^([+-]?[0-9A-Fa-f]+)(?:\.([0-9A-Fa-f]+))?(?:([pP@])([+-]?[0-9]+))?$)"_L1);
+ static const QRegularExpression genNumRegex(R"(^([+-]?[0-9A-Za-z]+)(?:\.([0-9A-Za-z]+))?(?:(@)([+-]?[0-9]+))?$)"_L1);
+
+ QRegularExpressionMatch numMatch;
+ if (base == 2) {
+ numMatch = binNumRegex.matchView(str);
+ } else if (base <= 10) {
+ numMatch = decNumRegex.matchView(str);
+ } else if (base == 16) {
+ numMatch = hexNumRegex.matchView(str);
+ } else {
+ numMatch = genNumRegex.matchView(str);
+ }
+
+ if (!numMatch.hasMatch()) {
+ return nullptr;
+ }
+
+ QStringView fracStr = numMatch.capturedView(2);
+ QString numStr = numMatch.captured(1) + fracStr;
+ QString denStr = u'1' + QString(fracStr.length(), u'0');
+
+ int exp = numMatch.captured(4).toInt();
+ if (exp != 0) {
+ const bool powOfTwoExp = numMatch.capturedView(3).at(0).toLower() == u'p';
+ if (powOfTwoExp && base != 2) {
+ if (exp > 0) {
+ exp = 1 << exp;
+ qint64 den = 1;
+ if (!fracStr.isEmpty()) {
+ den = std::pow(base, fracStr.length());
+ }
+ // while (den < exp) {
+ // den *= base;
+ // numStr += u"0";
+ // }
+ if (den < exp) {
+ const int order = std::ceil((std::log(exp) - std::log(den)) / std::log(base));
+ if (order > 0) {
+ den *= std::pow(base, order);
+ numStr += QString(order, u'0');
+ }
+ }
+ denStr = QString::number(den / exp, base);
+ } else {
+ denStr.replace(0, 1, QString::number(1 >> exp, base));
+ }
+ } else {
+ (exp > 0 ? numStr : denStr) += QString(std::abs(exp), u'0');
+ }
+ }
+
+ return detail::knumber_fraction::fromString("%1/%2"_L1.arg(numStr, denStr), base);
+}
}
}
@@ -256,55 +318,69 @@ KNumber::KNumber()
//------------------------------------------------------------------------------
// Name: KNumber
//------------------------------------------------------------------------------
-KNumber::KNumber(const QString &s)
+KNumber::KNumber(const QString &s, int base)
: value_(nullptr)
{
- static const QRegularExpression special_regex(QLatin1String("^(inf|-inf|nan)$"));
- // const QRegularExpression integer_regex(QLatin1String("^[+-]?\\d+$"));
- static const QRegularExpression integer_regex(QLatin1String("^[+-]?\\[1-9]d+$"));
- static const QRegularExpression binary_integer_regex(QLatin1String("^0b[0-1]{1,64}$"));
- static const QRegularExpression octal_integer_regex(QLatin1String("^0[0-7]{1,21}$"));
- static const QRegularExpression hex_integer_regex(QLatin1String("^0x[0-9A-Fa-f]{1,16}$"));
- static const QRegularExpression fraction_regex(QLatin1String("^[+-]?\\d+/\\d+$"));
- const QRegularExpression float_regex(QString(QLatin1String(R"(^([+-]?\d*)(%1\d*)?([e|E]([+-]?\d+))?$)")).arg(QRegularExpression::escape(DecimalSeparator)));
-
- if (special_regex.match(s).hasMatch()) {
+ static const QRegularExpression specialRegex("^([+-]?inf|nan)$"_L1, QRegularExpression::CaseInsensitiveOption);
+ if (specialRegex.match(s).hasMatch()) {
value_ = new detail::knumber_error(s);
- } else if (integer_regex.match(s).hasMatch()) {
- value_ = new detail::knumber_integer(s);
- } else if (fraction_regex.match(s).hasMatch()) {
- value_ = new detail::knumber_fraction(s);
- simplify();
- } else if (hex_integer_regex.match(s).hasMatch() || octal_integer_regex.match(s).hasMatch() || binary_integer_regex.match(s).hasMatch()) {
- value_ = new detail::knumber_integer(s.toULongLong(nullptr, 0));
- } else if (const auto match = float_regex.match(s); match.hasMatch()) {
- if (detail::knumber_fraction::default_fractional_input) {
- const QString ipart = match.captured(1);
- const QString fpart = match.captured(2);
- const int e_val = match.captured(4).toInt();
-
- QString num = ipart + fpart.mid(1);
- QString den = QLatin1String("1") + QString(fpart.size() - 1, QLatin1Char('0'));
-
- if (e_val < 0) {
- den = den + QString(::abs(e_val), QLatin1Char('0'));
- } else if (e_val > 0) {
- num = num + QString(::abs(e_val), QLatin1Char('0'));
+ } else {
+ const QString str = s.trimmed().remove(GroupSeparator).replace(DecimalSeparator, "."_L1);
+ // QString str = s.trimmed().remove(GroupSeparator).replace(DecimalSeparator, "."_L1);
+ // if (base == 0) {
+ // base = 10;
+ // if (str.length() > 1 && str.at(0) == u'0') {
+ // const QChar c = str.at(1).toLower();
+ // if (c == u'x') {
+ // str = str.sliced(2);
+ // base = 16;
+ // } else if (c == u'o') {
+ // str = str.sliced(2);
+ // base = 8;
+ // } else if (c >= u'0' && c <= u'7') {
+ // str = str.sliced(1);
+ // base = 8;
+ // } else if (c == u'b') {
+ // str = str.sliced(2);
+ // base = 2;
+ // }
+ // }
+ // }
+
+ if (base >= 2 && base <= 36 && str.length() > 0) {
+ if (value_ = detail::knumber_integer::fromString(str, base); value_) {
+ return;
}
- value_ = new detail::knumber_fraction(QStringLiteral("%1/%2").arg(num, den));
- simplify();
- return;
- }
+ if (value_ = detail::knumber_fraction::fromString(str, base); value_) {
+ simplify();
+ return;
+ }
- // we need to normalize the decimal separator to US style because that's
- // the only type that the GMP function accept
- QString new_s = s;
- new_s.replace(DecimalSeparator, QLatin1String("."));
+ // std::unique_ptr<detail::knumber_float> num(detail::knumber_float::fromString(str, base));
+ // if (num) {
+ // if (detail::knumber_fraction::default_fractional_input) {
+ // value_ = new detail::knumber_fraction(num.get());
+ // } else {
+ // value_ = num.release();
+ // }
+ // simplify();
+ // return;
+ // }
+
+ if (detail::knumber_fraction::default_fractional_input) {
+ if (value_ = impl::parseFractionFromFloat(str, base); value_) {
+ simplify();
+ return;
+ }
+ }
+
+ if (value_ = detail::knumber_float::fromString(str, base); value_) {
+ simplify();
+ return;
+ }
+ }
- value_ = new detail::knumber_float(new_s);
- simplify();
- } else {
value_ = new detail::knumber_error(detail::knumber_error::ERROR_UNDEFINED);
}
}
diff --git a/knumber/knumber.h b/knumber/knumber.h
index aacdd4cafb3c81e3d49adb4d87b08ffa3ce0916a..b0006d942d83c9634876ed4e8052f941efb40735 100644
--- a/knumber/knumber.h
+++ b/knumber/knumber.h
@@ -45,7 +45,7 @@ public:
public:
// construction/destruction
KNumber();
- explicit KNumber(const QString &s);
+ explicit KNumber(const QString &s, int base = 10);
explicit KNumber(qint32 value);
explicit KNumber(qint64 value);
diff --git a/knumber/knumber_float.cpp b/knumber/knumber_float.cpp
index 83d059a4ab6a7e6899c55aac98cf996554f8f388..04e5545bc39bbecbb2880705d42a6109174e1785 100644
--- a/knumber/knumber_float.cpp
+++ b/knumber/knumber_float.cpp
@@ -79,14 +79,6 @@ knumber_base *knumber_float::execute_mpfr_func(mpfr_srcptr op)
return ensureIsValid(mpfr_);
}
-//------------------------------------------------------------------------------
-// Name:
-//------------------------------------------------------------------------------
-knumber_float::knumber_float(const QString &s)
-{
- mpfr_set_str(new_mpfr(), s.toLatin1().constData(), 10, rounding_mode);
-}
-
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
@@ -165,6 +157,27 @@ knumber_float::~knumber_float()
mpfr_clear(mpfr_);
}
+//------------------------------------------------------------------------------
+// Name: knumber_float
+//------------------------------------------------------------------------------
+knumber_float::knumber_float()
+{
+ mpfr_init(mpfr_);
+}
+
+//------------------------------------------------------------------------------
+// Name: fromString
+//------------------------------------------------------------------------------
+knumber_float* knumber_float::fromString(const QString &s, int base)
+{
+ std::unique_ptr<knumber_float> num(new knumber_float);
+ if (mpfr_set_str(num->mpfr_, qPrintable(s), base, rounding_mode) == 0) {
+ return num.release();
+ }
+
+ return nullptr;
+}
+
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
diff --git a/knumber/knumber_float.h b/knumber/knumber_float.h
index e009bcf25d5c12d26d5dedcc2c1f07e0860871ac..d8a9e5ef664be6d92ba95987dd11f6b8cae83130 100644
--- a/knumber/knumber_float.h
+++ b/knumber/knumber_float.h
@@ -25,7 +25,6 @@ private:
static const mpfr_prec_t precision;
public:
- explicit knumber_float(const QString &s);
explicit knumber_float(double value);
#ifdef HAVE_LONG_DOUBLE
explicit knumber_float(long double value);
@@ -34,6 +33,12 @@ public:
explicit knumber_float(mpfr_t mpfr);
~knumber_float() override;
+private:
+ knumber_float();
+
+public:
+ static knumber_float* fromString(const QString &s, int base);
+
private:
// conversion constructors
explicit knumber_float(const knumber_integer *value);
diff --git a/knumber/knumber_fraction.cpp b/knumber/knumber_fraction.cpp
index eab6d98a6d10b8c6ec092648a156c7a414b8d545..611e53cc18d875a0fa8f6e3153789f802505fa6b 100644
--- a/knumber/knumber_fraction.cpp
+++ b/knumber/knumber_fraction.cpp
@@ -41,16 +41,6 @@ void knumber_fraction::set_split_off_integer_for_fraction_output(bool value)
split_off_integer_for_fraction_output = value;
}
-//------------------------------------------------------------------------------
-// Name:
-//------------------------------------------------------------------------------
-knumber_fraction::knumber_fraction(const QString &s)
-{
- mpq_init(mpq_);
- mpq_set_str(mpq_, s.toLatin1().constData(), 10);
- mpq_canonicalize(mpq_);
-}
-
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
@@ -89,6 +79,15 @@ knumber_fraction::knumber_fraction(const knumber_fraction *value)
mpq_set(mpq_, value->mpq_);
}
+// //------------------------------------------------------------------------------
+// // Name: knumber_fraction
+// //------------------------------------------------------------------------------
+// knumber_fraction::knumber_fraction(const knumber_float *value)
+// {
+// mpq_init(mpq_);
+// mpfr_get_q(mpq_, value->mpfr_);
+// }
+
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
@@ -98,16 +97,6 @@ knumber_fraction::knumber_fraction(const knumber_integer *value)
mpq_set_z(mpq_, value->mpz_);
}
-#if 0
-//------------------------------------------------------------------------------
-// Name:
-//------------------------------------------------------------------------------
-knumber_fraction::knumber_fraction(const knumber_float *value) {
- mpq_init(mpq_);
- mpq_set_f(mpq_, value->mpf_);
-}
-#endif
-
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
@@ -124,6 +113,29 @@ knumber_fraction::~knumber_fraction()
mpq_clear(mpq_);
}
+//------------------------------------------------------------------------------
+// Name: knumber_fraction
+//------------------------------------------------------------------------------
+knumber_fraction::knumber_fraction()
+{
+ mpq_init(mpq_);
+}
+
+//------------------------------------------------------------------------------
+// Name: fromString
+//------------------------------------------------------------------------------
+knumber_fraction* knumber_fraction::fromString(const QString &s, int base)
+{
+ std::unique_ptr<knumber_fraction> num(new knumber_fraction);
+ if (mpq_set_str(num->mpq_, qPrintable(s), base) == 0) {
+ mpq_canonicalize(num->mpq_);
+
+ return num.release();
+ }
+
+ return nullptr;
+}
+
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
@@ -789,7 +801,7 @@ QString knumber_fraction::toStringInBase(int base, int precision) const
if (knumber_fraction::default_fractional_output) {
knumber_integer floor(this);
if (split_off_integer_for_fraction_output && !floor.is_zero()) {
- knumber_integer numerator(0), denominator(0);
+ knumber_integer numerator, denominator;
mpq_get_num(numerator.mpz_, mpq_);
mpq_get_den(denominator.mpz_, mpq_);
diff --git a/knumber/knumber_fraction.h b/knumber/knumber_fraction.h
index 651a28aeca04666b7efa8d2115a3668f91bd016f..c2a379fc9d45ad6587550a86a71df3166b92c34c 100644
--- a/knumber/knumber_fraction.h
+++ b/knumber/knumber_fraction.h
@@ -30,12 +30,17 @@ public:
static void set_split_off_integer_for_fraction_output(bool value);
public:
- explicit knumber_fraction(const QString &s);
knumber_fraction(qint64 num, quint64 den);
knumber_fraction(quint64 num, quint64 den);
explicit knumber_fraction(mpq_t mpq);
~knumber_fraction() override;
+private:
+ knumber_fraction();
+
+public:
+ static knumber_fraction* fromString(const QString &s, int base);
+
public:
knumber_base *clone() override;
@@ -110,11 +115,8 @@ private:
// conversion constructors
explicit knumber_fraction(const knumber_integer *value);
explicit knumber_fraction(const knumber_fraction *value);
-#if 0
- // TODO: this is omitted because there is no good way to
- // implement it
- knumber_fraction(const knumber_float *value);
-#endif
+ // TODO: this is omitted because there is no good way to implement it
+ // explicit knumber_fraction(const knumber_float *value);
explicit knumber_fraction(const knumber_error *value);
private:
diff --git a/knumber/knumber_integer.cpp b/knumber/knumber_integer.cpp
index 94e641bb3987a8e3903721644c49fb2bc0f189d4..b3948af4cb921dd43f20862a83ebb1c3128ab3a9 100644
--- a/knumber/knumber_integer.cpp
+++ b/knumber/knumber_integer.cpp
@@ -13,15 +13,6 @@
namespace detail
{
-//------------------------------------------------------------------------------
-// Name: knumber_integer
-//------------------------------------------------------------------------------
-knumber_integer::knumber_integer(const QString &s)
-{
- mpz_init(mpz_);
- mpz_set_str(mpz_, s.toLatin1().constData(), 10);
-}
-
//------------------------------------------------------------------------------
// Name: knumber_integer
//------------------------------------------------------------------------------
@@ -129,6 +120,27 @@ knumber_integer::~knumber_integer()
mpz_clear(mpz_);
}
+//------------------------------------------------------------------------------
+// Name: knumber_integer
+//------------------------------------------------------------------------------
+knumber_integer::knumber_integer()
+{
+ mpz_init(mpz_);
+}
+
+//------------------------------------------------------------------------------
+// Name: fromString
+//------------------------------------------------------------------------------
+knumber_integer* knumber_integer::fromString(const QString &s, int base)
+{
+ std::unique_ptr<knumber_integer> num(new knumber_integer);
+ if (mpz_set_str(num->mpz_, qPrintable(s), base) == 0) {
+ return num.release();
+ }
+
+ return nullptr;
+}
+
//------------------------------------------------------------------------------
// Name: add
//------------------------------------------------------------------------------
diff --git a/knumber/knumber_integer.h b/knumber/knumber_integer.h
index 17b201e614161f6947b55a6701157680040c31b2..390e6072709b1945d649bba6e653e33ade0823e7 100644
--- a/knumber/knumber_integer.h
+++ b/knumber/knumber_integer.h
@@ -20,7 +20,6 @@ class knumber_integer : public knumber_base
friend class knumber_float;
public:
- explicit knumber_integer(const QString &s);
explicit knumber_integer(qint32 value);
explicit knumber_integer(qint64 value);
explicit knumber_integer(quint32 value);
@@ -28,6 +27,12 @@ public:
explicit knumber_integer(mpz_t mpz);
~knumber_integer() override;
+private:
+ knumber_integer();
+
+public:
+ static knumber_integer* fromString(const QString &s, int base);
+
public:
knumber_base *clone() override;
diff --git a/knumber/tests/knumbertest.cpp b/knumber/tests/knumbertest.cpp
index a3a97eae7040a6e4076b25b08c82ee70bc891c13..ded3791d4319736aaefd1c1a1a14298c42e5635a 100644
--- a/knumber/tests/knumbertest.cpp
+++ b/knumber/tests/knumbertest.cpp
@@ -872,6 +872,7 @@ void testingOutput()
void testingConstructors()
{
+ std::cout << "\n\n";
std::cout << "Testing Constructors:\n";
std::cout << "---------------------\n";
@@ -901,25 +902,31 @@ void testingConstructors()
checkResult(QStringLiteral("KNumber(\"-inf\")"), KNumber(QStringLiteral("-inf")), QStringLiteral("-inf"), KNumber::TYPE_ERROR);
// test accepting of non-US number formatted strings
+ const QString decimalSeparator = KNumber::decimalSeparator();
+ const QString groupSeparator = KNumber::groupSeparator();
KNumber::setDecimalSeparator(QStringLiteral(","));
+ KNumber::setGroupSeparator(QStringLiteral(" "));
checkResult(QStringLiteral("KNumber(\"5,2\")"), KNumber(QStringLiteral("5,2")), QStringLiteral("5,2"), KNumber::TYPE_FLOAT);
- KNumber::setDecimalSeparator(QStringLiteral("."));
-
- checkResult(QStringLiteral("KNumber(\"0b1110001111\")"), KNumber(QStringLiteral("0b1110001111")), QStringLiteral("911"), KNumber::TYPE_INTEGER);
- checkResult(QStringLiteral("KNumber(\"0b00010101010111\")"), KNumber(QStringLiteral("0b00010101010111")), QStringLiteral("1367"), KNumber::TYPE_INTEGER);
- checkResult(QStringLiteral("KNumber(\"0b11\")"), KNumber(QStringLiteral("0b11")), QStringLiteral("3"), KNumber::TYPE_INTEGER);
- checkResult(QStringLiteral("KNumber(\"0b00000000000000001\")"), KNumber(QStringLiteral("0b00000000000000001")), QStringLiteral("1"), KNumber::TYPE_INTEGER);
-
- checkResult(QStringLiteral("KNumber(\"077\")"), KNumber(QStringLiteral("077")), QStringLiteral("63"), KNumber::TYPE_INTEGER);
- checkResult(QStringLiteral("KNumber(\"0077\")"), KNumber(QStringLiteral("0077")), QStringLiteral("63"), KNumber::TYPE_INTEGER);
-
- checkResult(QStringLiteral("KNumber(\"0xFF\")"), KNumber(QStringLiteral("0xFF")), QStringLiteral("255"), KNumber::TYPE_INTEGER);
- checkResult(QStringLiteral("KNumber(\"0xFf\")"), KNumber(QStringLiteral("0xFf")), QStringLiteral("255"), KNumber::TYPE_INTEGER);
- checkResult(QStringLiteral("KNumber(\"0x0A\")"), KNumber(QStringLiteral("0x0A")), QStringLiteral("10"), KNumber::TYPE_INTEGER);
- checkResult(QStringLiteral("KNumber(\"0x0a\")"), KNumber(QStringLiteral("0x0a")), QStringLiteral("10"), KNumber::TYPE_INTEGER);
- checkResult(QStringLiteral("KNumber(\"0x0000a\")"), KNumber(QStringLiteral("0x0000a")), QStringLiteral("10"), KNumber::TYPE_INTEGER);
- checkResult(QStringLiteral("KNumber(\"0xabcdef\")"), KNumber(QStringLiteral("0xabcdef")), QStringLiteral("11259375"), KNumber::TYPE_INTEGER);
- checkResult(QStringLiteral("KNumber(\"0xAbCdEf\")"), KNumber(QStringLiteral("0xAbCdEf")), QStringLiteral("11259375"), KNumber::TYPE_INTEGER);
+ KNumber::setDecimalSeparator(decimalSeparator);
+ KNumber::setGroupSeparator(groupSeparator);
+
+ // checkResult(QStringLiteral("KNumber(\"0b1110001111\")"), KNumber(QStringLiteral("0b1110001111")), QStringLiteral("911"), KNumber::TYPE_INTEGER);
+ // checkResult(QStringLiteral("KNumber(\"0b00010101010111\")"), KNumber(QStringLiteral("0b00010101010111")), QStringLiteral("1367"), KNumber::TYPE_INTEGER);
+ // checkResult(QStringLiteral("KNumber(\"0b11\")"), KNumber(QStringLiteral("0b11")), QStringLiteral("3"), KNumber::TYPE_INTEGER);
+ // checkResult(QStringLiteral("KNumber(\"0b00000000000000001\")"), KNumber(QStringLiteral("0b00000000000000001")), QStringLiteral("1"), KNumber::TYPE_INTEGER);
+
+ // checkResult(QStringLiteral("KNumber(\"077\")"), KNumber(QStringLiteral("077")), QStringLiteral("63"), KNumber::TYPE_INTEGER);
+ // checkResult(QStringLiteral("KNumber(\"0077\")"), KNumber(QStringLiteral("0077")), QStringLiteral("63"), KNumber::TYPE_INTEGER);
+ // checkResult(QStringLiteral("KNumber(\"0o77\")"), KNumber(QStringLiteral("0o77")), QStringLiteral("63"), KNumber::TYPE_INTEGER);
+ // checkResult(QStringLiteral("KNumber(\"0o077\")"), KNumber(QStringLiteral("0o077")), QStringLiteral("63"), KNumber::TYPE_INTEGER);
+
+ // checkResult(QStringLiteral("KNumber(\"0xFF\")"), KNumber(QStringLiteral("0xFF")), QStringLiteral("255"), KNumber::TYPE_INTEGER);
+ // checkResult(QStringLiteral("KNumber(\"0xFf\")"), KNumber(QStringLiteral("0xFf")), QStringLiteral("255"), KNumber::TYPE_INTEGER);
+ // checkResult(QStringLiteral("KNumber(\"0x0A\")"), KNumber(QStringLiteral("0x0A")), QStringLiteral("10"), KNumber::TYPE_INTEGER);
+ // checkResult(QStringLiteral("KNumber(\"0x0a\")"), KNumber(QStringLiteral("0x0a")), QStringLiteral("10"), KNumber::TYPE_INTEGER);
+ // checkResult(QStringLiteral("KNumber(\"0x0000a\")"), KNumber(QStringLiteral("0x0000a")), QStringLiteral("10"), KNumber::TYPE_INTEGER);
+ // checkResult(QStringLiteral("KNumber(\"0xabcdef\")"), KNumber(QStringLiteral("0xabcdef")), QStringLiteral("11259375"), KNumber::TYPE_INTEGER);
+ // checkResult(QStringLiteral("KNumber(\"0xAbCdEf\")"), KNumber(QStringLiteral("0xAbCdEf")), QStringLiteral("11259375"), KNumber::TYPE_INTEGER);
}
void testingConstants()
@@ -958,7 +965,10 @@ void testingRound()
std::cout << "\n\n";
std::cout << "Testing rounding numbers to precision=2 and localized decimal separator:\n";
std::cout << "----------\n";
+ const QString decimalSeparator = KNumber::decimalSeparator();
+ const QString groupSeparator = KNumber::groupSeparator();
KNumber::setDecimalSeparator(QStringLiteral(","));
+ KNumber::setGroupSeparator(QStringLiteral(" "));
checkTruth(QStringLiteral("KNumber(3) -> 3,00"), KNumber(QStringLiteral("3")).toQString(-1, 2) == QStringLiteral("3,00"), true);
checkTruth(QStringLiteral("KNumber(3,) -> 3,00"), KNumber(QStringLiteral("3,")).toQString(-1, 2) == QStringLiteral("3,00"), true);
checkTruth(QStringLiteral("KNumber(3,0) -> 3,00"), KNumber(QStringLiteral("3,0")).toQString(-1, 2) == QStringLiteral("3,00"), true);
@@ -972,7 +982,8 @@ void testingRound()
checkTruth(QStringLiteral("KNumber(3,999) -> 4,00"), KNumber(QStringLiteral("3,999")).toQString(-1, 2) == QStringLiteral("4,00"), true);
checkTruth(QStringLiteral("KNumber(3,9099)-> 3,91"), KNumber(QStringLiteral("3,9099")).toQString(-1, 2) == QStringLiteral("3,91"), true);
checkTruth(QStringLiteral("KNumber(9,999) -> 10,00"), KNumber(QStringLiteral("9,999")).toQString(-1, 2) == QStringLiteral("10,00"), true);
- KNumber::setDecimalSeparator(QStringLiteral("."));
+ KNumber::setDecimalSeparator(decimalSeparator);
+ KNumber::setGroupSeparator(groupSeparator);
}
}