Skip to content

Commit 1e4104d

Browse files
author
Paweł Salawa
committed
#5450 Further improvement for scientific and decimal notation of real numbers.
1 parent 433d52a commit 1e4104d

5 files changed

Lines changed: 47 additions & 30 deletions

File tree

SQLiteStudio3/Tests/UtilsTest/tst_utilssqltest.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,14 @@ void UtilsSqlTest::testDoubleToString()
8080
{
8181
QVERIFY(doubleToString(QVariant(5.001)) == "5.001");
8282
QVERIFY(doubleToString(QVariant(5.0000001)) == "5.0000001");
83-
QVERIFY(doubleToString(QVariant(5.000000000000000000000000001)) == "5.0"); // too big, considered as round 5
83+
QVERIFY(doubleToString(QVariant(5.000000000000000000000000001)) == "5.0"); // spread of information is too big, considered as round 5
8484
QVERIFY(doubleToString(QVariant(0.0000001)) == "0.0000001");
8585
QVERIFY(doubleToString(QVariant(9.99999999999998)) == "9.99999999999998");
8686
QVERIFY(doubleToString(QVariant(0.1 + 0.1 + 0.1)) == "0.3");
87+
QVERIFY(doubleToString(QVariant(1e-10)) == "0.0000000001");
88+
QVERIFY(doubleToString(QVariant(1e-15)) == "0.000000000000001");
89+
QVERIFY(doubleToString(QVariant(1e-17)) == "1e-17");
90+
QVERIFY(doubleToString(QVariant(1e+20)) == "100000000000000000000.0");
8791
}
8892

8993
QTEST_APPLESS_MAIN(UtilsSqlTest)

SQLiteStudio3/coreSQLiteStudio/common/utils.cpp

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -964,21 +964,39 @@ QStringList concat(const QList<QStringList>& list)
964964
}
965965

966966

967-
QString doubleToString(const QVariant& val)
967+
QString doubleToString(const QVariant& val, bool enforceDecimal)
968968
{
969969
double d = val.toDouble();
970-
QString str = QString::number(d, 'f', 17);
970+
if (std::isnan(d) || std::isinf(d))
971+
return QString();
971972

972-
while (str.contains('.') && str.endsWith('0'))
973-
str.chop(1);
973+
double absd = std::fabs(d);
974+
if (absd == 0.0)
975+
return "0.0";
974976

975-
if (str.endsWith('.'))
976-
str.chop(1);
977+
int k = static_cast<int>(std::floor(std::log10(absd)));
978+
QString result;
979+
if (k < -16 && !enforceDecimal)
980+
{
981+
// Scientific notation
982+
result = QString::number(d, 'g', 15);
983+
}
984+
else
985+
{
986+
// Decimal notation
987+
int decimals = std::max(0, 15 - (k + 1));
988+
result = QString::number(d, 'f', decimals);
989+
while (result.contains('.') && result.endsWith('0'))
990+
result.chop(1);
991+
992+
if (result.endsWith('.'))
993+
result.chop(1);
994+
}
977995

978-
if (!str.contains('.'))
979-
str += ".0";
996+
if (!result.contains('.') && !result.contains('e'))
997+
result += ".0";
980998

981-
return str;
999+
return result;
9821000
}
9831001

9841002
void sortWithReferenceList(QList<QString>& listToSort, const QList<QString>& referenceList, Qt::CaseSensitivity cs)

SQLiteStudio3/coreSQLiteStudio/common/utils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ API_EXPORT bool renameBetweenPartitions(const QString& src, const QString& dst);
276276
API_EXPORT bool isWritableRecursively(const QString& dir);
277277
API_EXPORT QString encryptRsa(const QString& input, const QString& modulus, const QString& exponent);
278278
API_EXPORT QString decryptRsa(const QString& input, const QString& modulus, const QString& exponent);
279-
API_EXPORT QString doubleToString(const QVariant& val);
279+
API_EXPORT QString doubleToString(const QVariant& val, bool enforceDecimal = false);
280280

281281
/**
282282
* @brief Sorts string list using reference list for ordering.

SQLiteStudio3/guiSQLiteStudio/datagrid/sqlqueryitemdelegate.cpp

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,7 @@ QString SqlQueryItemDelegate::displayText(const QVariant& value, const QLocale&
9595
UNUSED(locale);
9696

9797
if (value.type() == QVariant::Double)
98-
{
99-
if (CFG_UI.General.UseSciFormatForDoubles.get())
100-
return value.toString();
101-
else
102-
return doubleToString(value);
103-
}
98+
return doubleToString(value, CFG_UI.General.UseSciFormatForDoubles.get());
10499

105100
return QStyledItemDelegate::displayText(value, locale);
106101
}
@@ -207,9 +202,9 @@ void SqlQueryItemDelegate::setModelDataForLineEdit(QLineEdit* editor, QAbstractI
207202
void SqlQueryItemDelegate::setEditorDataForLineEdit(QLineEdit* le, const QModelIndex& index) const
208203
{
209204
QVariant value = index.data(Qt::EditRole);
210-
if (value.userType() == QVariant::Double && !CFG_UI.General.UseSciFormatForDoubles.get())
205+
if (value.userType() == QVariant::Double)
211206
{
212-
le->setText(doubleToString(value));
207+
le->setText(doubleToString(value, !CFG_UI.General.UseSciFormatForDoubles.get()));
213208
return;
214209
}
215210

SQLiteStudio3/guiSQLiteStudio/dialogs/configdialog.ui

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<x>0</x>
88
<y>0</y>
99
<width>866</width>
10-
<height>580</height>
10+
<height>589</height>
1111
</rect>
1212
</property>
1313
<property name="windowTitle">
@@ -241,7 +241,7 @@
241241
</sizepolicy>
242242
</property>
243243
<property name="currentIndex">
244-
<number>4</number>
244+
<number>1</number>
245245
</property>
246246
<widget class="QWidget" name="databaseListPage">
247247
<layout class="QVBoxLayout" name="verticalLayout_36">
@@ -419,8 +419,8 @@
419419
<rect>
420420
<x>0</x>
421421
<y>0</y>
422-
<width>433</width>
423-
<height>718</height>
422+
<width>660</width>
423+
<height>726</height>
424424
</rect>
425425
</property>
426426
<layout class="QVBoxLayout" name="verticalLayout_34">
@@ -534,10 +534,10 @@
534534
<item row="6" column="0">
535535
<widget class="QCheckBox" name="useSciFormatForDoublesCheck">
536536
<property name="toolTip">
537-
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;By default (when this option is disabled) a real number is displayed in the format of decimals with decimal point. In some cases, when the number is really small (several places after decimal point), the default representation may appear inaccurate. In such case you may want to enable this option to use the scientific notation (i.e. &lt;span style=&quot; font-style:italic;&quot;&gt;5.3e-21&lt;/span&gt;).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
537+
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;When enabled, SQLiteStudio automatically switches to scientific notation for very small real numbers (e.g. &lt;span style=&quot; font-style:italic;&quot;&gt;5.3e-21&lt;/span&gt;).&lt;br/&gt;Decimal notation is used for values whose magnitude allows a readable decimal representation.&lt;/p&gt;&lt;p&gt;When disabled, real numbers are always displayed using decimal notation, even if this results in very long fractional parts.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
538538
</property>
539539
<property name="text">
540-
<string>Use scientific notation for real numbers in the grid view</string>
540+
<string>Use scientific notation for very small real numbers in the grid view</string>
541541
</property>
542542
<property name="cfg" stdset="0">
543543
<string notr="true">General.UseSciFormatForDoubles</string>
@@ -1574,8 +1574,8 @@
15741574
<rect>
15751575
<x>0</x>
15761576
<y>0</y>
1577-
<width>364</width>
1578-
<height>283</height>
1577+
<width>389</width>
1578+
<height>288</height>
15791579
</rect>
15801580
</property>
15811581
<layout class="QVBoxLayout" name="verticalLayout_31">
@@ -1998,7 +1998,7 @@ p, li { white-space: pre-wrap; }
19981998
hr { height: 1px; border-width: 0; }
19991999
li.unchecked::marker { content: &quot;\2610&quot;; }
20002000
li.checked::marker { content: &quot;\2612&quot;; }
2001-
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Segoe UI'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
2001+
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
20022002
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-size:8pt;&quot;&gt;Abcdefgh&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
20032003
</property>
20042004
</widget>
@@ -2089,8 +2089,8 @@ li.checked::marker { content: &quot;\2612&quot;; }
20892089
<rect>
20902090
<x>0</x>
20912091
<y>0</y>
2092-
<width>222</width>
2093-
<height>313</height>
2092+
<width>235</width>
2093+
<height>318</height>
20942094
</rect>
20952095
</property>
20962096
<layout class="QVBoxLayout" name="verticalLayout_9">

0 commit comments

Comments
 (0)