Change QString formatting of negative numbers in non-base-10

For bases other than 10, negative numbers have been converted
to QString by casting them to an unsigned number and
converting that. Thus QString::number(-17, 16) returned
"0xffffffffffffffef", for example.
This patch changes the behavior so that
negative numbers are converted like positive numbers.
Additinally, this patch adds unit tests for QString::number.

[ChangeLog][Important Behavior Changes]
Changed QString::number(integer, base) for negative numbers
and bases other than 10 to return the string corresponding
to the absolute value, prefixed by "-".

Fixes: QTBUG-53706
Change-Id: I0ad3ca3f035d553860b262f5bec17dc81714d8ac
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Andreas Buhr 2020-10-27 10:11:31 +01:00 committed by Thiago Macieira
parent 0732c5917d
commit 98666c8afc
2 changed files with 64 additions and 6 deletions

View File

@ -3491,12 +3491,6 @@ QString QLocaleData::longLongToString(qlonglong l, int precision,
int base, int width, unsigned flags) const
{
bool negative = l < 0;
if (base != 10) {
// these are not supported by sprintf for octal and hex
flags &= ~AlwaysShowSign;
flags &= ~BlankBeforePositive;
negative = false; // neither are negative numbers
}
QT_WARNING_PUSH
/* "unary minus operator applied to unsigned type, result still unsigned" */

View File

@ -519,6 +519,8 @@ private slots:
void toUcs4();
void arg();
void number();
void number_base_data();
void number_base();
void doubleOut();
void arg_fillChar_data();
void arg_fillChar();
@ -4793,6 +4795,68 @@ void tst_QString::number()
#endif
}
void tst_QString::number_base_data()
{
QTest::addColumn<qlonglong>("n");
QTest::addColumn<int>("base");
QTest::addColumn<QString>("expected");
QTest::newRow("base 10, positive") << 12346LL << 10 << QString("12346");
QTest::newRow("base 2, positive") << 12346LL << 2 << QString("11000000111010");
QTest::newRow("base 8, positive") << 12346LL << 8 << QString("30072");
QTest::newRow("base 16, positive") << 12346LL << 16 << QString("303a");
QTest::newRow("base 17, positive") << 12346LL << 17 << QString("28c4");
QTest::newRow("base 36, positive") << 2181789482LL << 36 << QString("102zbje");
QTest::newRow("base 10, negative") << -12346LL << 10 << QString("-12346");
QTest::newRow("base 2, negative") << -12346LL << 2 << QString("-11000000111010");
QTest::newRow("base 8, negative") << -12346LL << 8 << QString("-30072");
QTest::newRow("base 16, negative") << -12346LL << 16 << QString("-303a");
QTest::newRow("base 17, negative") << -12346LL << 17 << QString("-28c4");
QTest::newRow("base 36, negative") << -2181789482LL << 36 << QString("-102zbje");
QTest::newRow("base 2, negative") << -1LL << 2 << QString("-1");
QTest::newRow("largeint, base 10, positive")
<< 123456789012LL << 10 << QString("123456789012");
QTest::newRow("largeint, base 2, positive")
<< 123456789012LL << 2 << QString("1110010111110100110010001101000010100");
QTest::newRow("largeint, base 8, positive")
<< 123456789012LL << 8 << QString("1627646215024");
QTest::newRow("largeint, base 16, positive")
<< 123456789012LL << 16 << QString("1cbe991a14");
QTest::newRow("largeint, base 17, positive")
<< 123456789012LL << 17 << QString("10bec2b629");
QTest::newRow("largeint, base 10, negative")
<< -123456789012LL << 10 << QString("-123456789012");
QTest::newRow("largeint, base 2, negative")
<< -123456789012LL << 2 << QString("-1110010111110100110010001101000010100");
QTest::newRow("largeint, base 8, negative")
<< -123456789012LL << 8 << QString("-1627646215024");
QTest::newRow("largeint, base 16, negative")
<< -123456789012LL << 16 << QString("-1cbe991a14");
QTest::newRow("largeint, base 17, negative")
<< -123456789012LL << 17 << QString("-10bec2b629");
}
void tst_QString::number_base()
{
QFETCH( qlonglong, n );
QFETCH( int, base );
QFETCH( QString, expected );
QCOMPARE(QString::number(n, base), expected);
// check qlonglong->QString->qlonglong round trip
for (int ibase = 2; ibase <= 36; ++ibase) {
auto stringrep = QString::number(n, ibase);
bool ok(false);
auto result = stringrep.toLongLong(&ok, ibase);
QVERIFY(ok);
QCOMPARE(n, result);
}
}
void tst_QString::doubleOut()
{
// Regression test for QTBUG-63620; the first two paths lost the exponent's