diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 5e0e93d7a..80fe32852 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -1139,20 +1139,16 @@ void MainWindow::updateGUI() {
html += "qBittorrent";
html += "";
html += "
";
- /* HACK because QString rounds up. Eg QString::number(0.999*100.0, 'f' ,1) == 99.9
- ** but QString::number(0.9999*100.0, 'f' ,1) == 100.0 */
- html += "
"+tr("DL speed: %1 KiB/s", "e.g: Download speed: 10 KiB/s").arg(QString::number((int)((QBtSession::instance()->getPayloadDownloadRate()/1024.)*10)/10.0, 'f', 1));
+ html += "
"+tr("DL speed: %1 KiB/s", "e.g: Download speed: 10 KiB/s").arg(misc::accurateDoubleToString(QBtSession::instance()->getPayloadDownloadRate()/1024., 1));
html += "
";
html += "";
- html += "
"+tr("UP speed: %1 KiB/s", "e.g: Upload speed: 10 KiB/s").arg(QString::number((int)((QBtSession::instance()->getPayloadUploadRate()/1024.)*10)/10.0, 'f', 1));
+ html += "
"+tr("UP speed: %1 KiB/s", "e.g: Upload speed: 10 KiB/s").arg(misc::accurateDoubleToString(QBtSession::instance()->getPayloadUploadRate()/1024., 1));
html += "
";
#else
// OSes such as Windows do not support html here
- /* HACK because QString rounds up. Eg QString::number(0.999*100.0, 'f' ,1) == 99.9
- ** but QString::number(0.9999*100.0, 'f' ,1) == 100.0 */
- QString html =tr("DL speed: %1 KiB/s", "e.g: Download speed: 10 KiB/s").arg(QString::number((int)((QBtSession::instance()->getPayloadDownloadRate()/1024.)*10)/10.0, 'f', 1));
+ QString html =tr("DL speed: %1 KiB/s", "e.g: Download speed: 10 KiB/s").arg(misc::accurateDoubleToString(QBtSession::instance()->getPayloadDownloadRate()/1024., 1));
html += "\n";
- html += tr("UP speed: %1 KiB/s", "e.g: Upload speed: 10 KiB/s").arg(QString::number((int)((QBtSession::instance()->getPayloadUploadRate()/1024.)*10)/10.0, 'f', 1));
+ html += tr("UP speed: %1 KiB/s", "e.g: Upload speed: 10 KiB/s").arg(misc::accurateDoubleToString(QBtSession::instance()->getPayloadUploadRate()/1024., 1));
#endif
systrayIcon->setToolTip(html); // tray icon
}
diff --git a/src/misc.cpp b/src/misc.cpp
index 2cc473e4e..b236d1cde 100644
--- a/src/misc.cpp
+++ b/src/misc.cpp
@@ -30,6 +30,8 @@
#include "misc.h"
+#include
+
#include
#include
#include
@@ -38,6 +40,7 @@
#include
#include
#include
+#include
#ifdef DISABLE_GUI
#include
@@ -255,9 +258,7 @@ QString misc::friendlyUnit(qreal val, bool is_speed) {
if (i == 0)
ret = QString::number((long)val) + " " + QCoreApplication::translate("misc", units[0].source, units[0].comment);
else
- /* HACK because QString rounds up. Eg QString::number(0.999*100.0, 'f' ,1) == 99.9
- ** but QString::number(0.9999*100.0, 'f' ,1) == 100.0 */
- ret = QString::number((int)(val*10)/10.0, 'f', 1) + " " + QCoreApplication::translate("misc", units[i].source, units[i].comment);
+ ret = accurateDoubleToString(val, 1) + " " + QCoreApplication::translate("misc", units[i].source, units[i].comment);
if (is_speed)
ret += QCoreApplication::translate("misc", "/s", "per second");
return ret;
@@ -572,3 +573,18 @@ bool misc::naturalSort(QString left, QString right, bool &result) { // uses less
return false;
}
#endif
+
+QString misc::accurateDoubleToString(double n, int precision) {
+ /* HACK because QString rounds up. Eg QString::number(0.999*100.0, 'f' ,1) == 99.9
+ ** but QString::number(0.9999*100.0, 'f' ,1) == 100.0 The problem manifests when
+ ** the number has more digits after the decimal than we want AND the digit after
+ ** our 'wanted' is >= 5. In this case our last digit gets rounded up. So for each
+ ** precision we add an extra 0 behind 1 in the below algorithm.
+ ** However this, approach has a drawback. eg (99,99, 2) returns 99.98 and (99.99, 3)
+ ** returns 99.989. This is a minor issue because mostly we want to use precision 1 or 2
+ ** and the double fed into this function will have more decimal places than required
+ ** precision anyway.*/
+
+ double prec = std::pow(10.0, precision);
+ return QLocale::system().toString((int)(n*(int)prec)/prec, 'f', precision);
+}
diff --git a/src/misc.h b/src/misc.h
index 16a52a721..ed4d498c0 100644
--- a/src/misc.h
+++ b/src/misc.h
@@ -108,6 +108,7 @@ namespace misc
QList boolListfromStringList(const QStringList &l);
QString toQString(time_t t);
+ QString accurateDoubleToString(double n, int precision);
#ifndef DISABLE_GUI
bool naturalSort(QString left, QString right, bool& result);
diff --git a/src/previewlistdelegate.h b/src/previewlistdelegate.h
index 65db98865..f6ba96e1b 100644
--- a/src/previewlistdelegate.h
+++ b/src/previewlistdelegate.h
@@ -65,9 +65,7 @@ class PreviewListDelegate: public QItemDelegate {
QStyleOptionProgressBarV2 newopt;
qreal progress = index.data().toDouble()*100.;
newopt.rect = opt.rect;
- /* HACK because QString rounds up. Eg QString::number(0.999*100.0, 'f' ,1) == 99.9
- ** but QString::number(0.9999*100.0, 'f' ,1) == 100.0 */
- newopt.text = QString::number((int)(progress*10)/10.0, 'f', 1)+"%";
+ newopt.text = misc::accurateDoubleToString(progress, 1);
newopt.progress = (int)progress;
newopt.maximum = 100;
newopt.minimum = 0;
diff --git a/src/properties/peerlistdelegate.h b/src/properties/peerlistdelegate.h
index 30e8345be..c819c544b 100644
--- a/src/properties/peerlistdelegate.h
+++ b/src/properties/peerlistdelegate.h
@@ -67,9 +67,7 @@ public:
case PROGRESS:{
QItemDelegate::drawBackground(painter, opt, index);
qreal progress = index.data().toDouble();
- /* HACK because QString rounds up. Eg QString::number(0.999*100.0, 'f' ,1) == 99.9
- ** but QString::number(0.9999*100.0, 'f' ,1) == 100.0 */
- QItemDelegate::drawDisplay(painter, opt, opt.rect, QString::number((int)((progress*100.0)*10)/10.0, 'f', 1)+"%");
+ QItemDelegate::drawDisplay(painter, opt, opt.rect, misc::accurateDoubleToString(progress*100.0, 1)+"%");
break;
}
default:
diff --git a/src/properties/propertieswidget.cpp b/src/properties/propertieswidget.cpp
index 49a581373..91ebdf91d 100644
--- a/src/properties/propertieswidget.cpp
+++ b/src/properties/propertieswidget.cpp
@@ -336,9 +336,7 @@ void PropertiesWidget::loadDynamicData() {
reannounce_lbl->setText(h.next_announce());
// Update ratio info
const qreal ratio = QBtSession::instance()->getRealRatio(h.hash());
- /* HACK because QString rounds up. Eg QString::number(0.999*100.0, 'f' ,1) == 99.9
- ** but QString::number(0.9999*100.0, 'f' ,1) == 100.0 */
- shareRatio->setText(ratio > QBtSession::MAX_RATIO ? QString::fromUtf8("∞") : QString::number((int)(ratio*100)/100.0, 'f', 2));
+ shareRatio->setText(ratio > QBtSession::MAX_RATIO ? QString::fromUtf8("∞") : misc::accurateDoubleToString(ratio*100, 2));
if (!h.is_seed()) {
showPiecesDownloaded(true);
// Downloaded pieces
@@ -355,17 +353,13 @@ void PropertiesWidget::loadDynamicData() {
std::vector avail;
h.piece_availability(avail);
pieces_availability->setAvailability(avail);
- /* HACK because QString rounds up. Eg QString::number(0.999*100.0, 'f' ,1) == 99.9
- ** but QString::number(0.9999*100.0, 'f' ,1) == 100.0 */
- avail_average_lbl->setText(QString::number((int)(h.distributed_copies()*1000)/1000.0, 'f', 3));
+ avail_average_lbl->setText(misc::accurateDoubleToString(h.distributed_copies(), 3));
} else {
showPiecesAvailability(false);
}
// Progress
qreal progress = h.progress()*100.;
- /* HACK because QString rounds up. Eg QString::number(0.999*100.0, 'f' ,1) == 99.9
- ** but QString::number(0.9999*100.0, 'f' ,1) == 100.0 */
- progress_lbl->setText(QString::number((int)(progress*10)/10.0, 'f', 1)+"%");
+ progress_lbl->setText(misc::accurateDoubleToString(progress, 1)+"%");
} else {
showPiecesAvailability(false);
showPiecesDownloaded(false);
diff --git a/src/properties/proplistdelegate.h b/src/properties/proplistdelegate.h
index 3b03b41fb..8ee055e3f 100644
--- a/src/properties/proplistdelegate.h
+++ b/src/properties/proplistdelegate.h
@@ -78,9 +78,7 @@ public:
QStyleOptionProgressBarV2 newopt;
qreal progress = index.data().toDouble()*100.;
newopt.rect = opt.rect;
- /* HACK because QString rounds up. Eg QString::number(0.999*100.0, 'f' ,1) == 99.9
- ** but QString::number(0.9999*100.0, 'f' ,1) == 100.0 */
- newopt.text = QString::number((int)(progress*10)/10.0, 'f', 1)+"%";
+ newopt.text = misc::accurateDoubleToString(progress, 1);
newopt.progress = (int)progress;
newopt.maximum = 100;
newopt.minimum = 0;
diff --git a/src/statsdialog.cpp b/src/statsdialog.cpp
index e514e9fa7..7f6d27640 100644
--- a/src/statsdialog.cpp
+++ b/src/statsdialog.cpp
@@ -67,13 +67,13 @@ void StatsDialog::updateUI() {
// Global ratio
ui->labelGlobalRatio->setText(
( atd > 0 && atu > 0 ) ?
- QString::number( (qreal)atu / (qreal)atd, 'f', 2) :
+ misc::accurateDoubleToString((qreal)atu / (qreal)atd, 2) :
"-"
);
// Cache hits
ui->labelCacheHits->setText(
( cache.blocks_read > 0 && cache.blocks_read_hit > 0 ) ?
- QString("%L1\%").arg(100. * (qreal)cache.blocks_read_hit / (qreal)cache.blocks_read, 0, 'f', 2) :
+ misc::accurateDoubleToString(100. * (qreal)cache.blocks_read_hit / (qreal)cache.blocks_read, 2) :
"-"
);
// Buffers size
@@ -91,12 +91,12 @@ void StatsDialog::updateUI() {
peers += (*iBegin).status().num_peers;
ui->labelWriteStarve->setText(
( ss.disk_write_queue > 0 && peers > 0 ) ?
- QString("%L1\%").arg(100. * (qreal)ss.disk_write_queue / (qreal)peers, 0, 'f', 2) :
+ misc::accurateDoubleToString(100. * (qreal)ss.disk_write_queue / (qreal)peers, 2) :
QString("0\%")
);
ui->labelReadStarve->setText(
( ss.disk_read_queue > 0 && peers > 0 ) ?
- QString("%L1\%").arg(100. * (qreal)ss.disk_read_queue / (qreal)peers, 0, 'f', 2) :
+ misc::accurateDoubleToString(100. * (qreal)ss.disk_read_queue / (qreal)peers, 2) :
QString("0\%")
);
// Disk queues
diff --git a/src/transferlistdelegate.h b/src/transferlistdelegate.h
index 96b892d3b..4158ac5c6 100644
--- a/src/transferlistdelegate.h
+++ b/src/transferlistdelegate.h
@@ -138,9 +138,7 @@ public:
case TorrentModelItem::TR_DLLIMIT:{
QItemDelegate::drawBackground(painter, opt, index);
const qlonglong limit = index.data().toLongLong();
- /* HACK because QString rounds up. Eg QString::number(0.999*100.0, 'f' ,1) == 99.9
- ** but QString::number(0.9999*100.0, 'f' ,1) == 100.0 */
- QItemDelegate::drawDisplay(painter, opt, opt.rect, limit > 0 ? QString::number((int)((limit/1024.)*10)/10.0, 'f', 1) + " " + tr("KiB/s", "KiB/second (.i.e per second)") : QString::fromUtf8("∞"));
+ QItemDelegate::drawDisplay(painter, opt, opt.rect, limit > 0 ? misc::accurateDoubleToString(limit/1024., 1) + " " + tr("KiB/s", "KiB/second (.i.e per second)") : QString::fromUtf8("∞"));
break;
}
case TorrentModelItem::TR_TIME_ELAPSED: {
@@ -160,9 +158,7 @@ public:
case TorrentModelItem::TR_RATIO:{
QItemDelegate::drawBackground(painter, opt, index);
const qreal ratio = index.data().toDouble();
- /* HACK because QString rounds up. Eg QString::number(0.999*100.0, 'f' ,1) == 99.9
- ** but QString::number(0.9999*100.0, 'f' ,1) == 100.0 */
- QItemDelegate::drawDisplay(painter, opt, opt.rect, ratio > QBtSession::MAX_RATIO ? QString::fromUtf8("∞") : QString::number((int)(ratio*100)/100.0, 'f', 2));
+ QItemDelegate::drawDisplay(painter, opt, opt.rect, ratio > QBtSession::MAX_RATIO ? QString::fromUtf8("∞") : misc::accurateDoubleToString(ratio, 2));
break;
}
case TorrentModelItem::TR_PRIORITY: {
@@ -179,9 +175,7 @@ public:
QStyleOptionProgressBarV2 newopt;
qreal progress = index.data().toDouble()*100.;
newopt.rect = opt.rect;
- /* HACK because QString rounds up. Eg QString::number(0.999*100.0, 'f' ,1) == 99.9
- ** but QString::number(0.9999*100.0, 'f' ,1) == 100.0 */
- newopt.text = QString::number((int)(progress*10)/10.0, 'f', 1)+"%";
+ newopt.text = misc::accurateDoubleToString(progress, 1);
newopt.progress = (int)progress;
newopt.maximum = 100;
newopt.minimum = 0;
diff --git a/src/webui/btjson.cpp b/src/webui/btjson.cpp
index 52da45303..b68bb2f69 100644
--- a/src/webui/btjson.cpp
+++ b/src/webui/btjson.cpp
@@ -143,9 +143,7 @@ static JsonDict toJson(const QTorrentHandle& h)
leechs += " ("+QString::number(h.num_incomplete())+")";
ret.add(KEY_TORRENT_LEECHS, leechs);
const qreal ratio = QBtSession::instance()->getRealRatio(h.hash());
- /* HACK because QString rounds up. Eg QString::number(0.999*100.0, 'f' ,1) == 99.9
- ** but QString::number(0.9999*100.0, 'f' ,1) == 100.0 */
- ret.add(KEY_TORRENT_RATIO, (ratio > 100.) ? QString::fromUtf8("∞") : QString::number((int)(ratio*10)/10.0, 'f', 1));
+ ret.add(KEY_TORRENT_RATIO, (ratio > 100.) ? QString::fromUtf8("∞") : misc::accurateDoubleToString(ratio, 1));
QString eta;
QString state;
if (h.is_paused()) {
@@ -307,9 +305,7 @@ QString btjson::getPropertiesForTorrent(const QString& hash)
data.add(KEY_PROP_TIME_ELAPSED, elapsed_txt);
data.add(KEY_PROP_CONNECT_COUNT, QString(QString::number(h.num_connections()) + " (" + tr("%1 max", "e.g. 10 max").arg(QString::number(h.connections_limit())) + ")"));
const qreal ratio = QBtSession::instance()->getRealRatio(h.hash());
- /* HACK because QString rounds up. Eg QString::number(0.999*100.0, 'f' ,1) == 99.9
- ** but QString::number(0.9999*100.0, 'f' ,1) == 100.0 */
- data.add(KEY_PROP_RATIO, ratio > 100. ? QString::fromUtf8("∞") : QString::number((int)(ratio*10)/10.0, 'f', 1));
+ data.add(KEY_PROP_RATIO, ratio > 100. ? QString::fromUtf8("∞") : misc::accurateDoubleToString(ratio, 1));
} catch(const std::exception& e) {
qWarning() << Q_FUNC_INFO << "Invalid torrent: " << e.what();
return QString();