Fix: For values of "Bytes transferred" and "Bytes/s" with 1000-based prefix names use 1000-based divisor instead of 1024-based#248
Conversation
src/qt/guiutil.cpp
Outdated
| return QString(QObject::tr("%1 B")).arg(bytes); | ||
| if(bytes < 1024 * 1024) | ||
| return QString(QObject::tr("%1 KB")).arg(bytes / 1024); | ||
| return QString(QObject::tr("%1 KiB")).arg(bytes / 1024); |
There was a problem hiding this comment.
| return QString(QObject::tr("%1 KiB")).arg(bytes / 1024); | |
| return QString(QObject::tr("%1 KB")).arg(bytes / 1000); |
Shouldn't we instead refactor to abide by the IEC 80000-13 standard where 1 KB=1000 bytes (base 10)? macOS and Unix use this IEC standard, Windows is one of the only systems still treating 1KB=1024 bytes (base 2).
Or determine the system type and use its standard. So for Unix/macOS systems use base 10, for Windows use base 2.
There was a problem hiding this comment.
I would be ok with that. Also with KB/s and change the divisor there accordingly form 1024 to 1000 (see e.g. Ubuntu units policy, which says for network bandwidth base-10 should be used). Whatever approach to solve, having unit KB with divisor 1024 is not correct I think. Edit: network bandwidth is something other than network throughput/transfer rate.
There was a problem hiding this comment.
@wodry yeah, I would say change this to base-10 instead and update the pr/commit description
There was a problem hiding this comment.
Changed the title to be open for either approach. Would like to see more opinions.
jarolrod
left a comment
There was a problem hiding this comment.
I think this mebibyte/gibibyte naming scheme can be confusing to non-technical users
|
Concept ACK on being consistent. My vote is for decimal prefixes for data transfer rates and amounts of the transferred data, that means usage of kB/s, kilobyte per second, and kB, kilobyte. Note, that the small letter "k" is a standard prefix that means "kilo". https://en.wikipedia.org/wiki/Data-rate_units#Unit_prefixes:
|
Thanks, so you would vote to change the divisor from 1024 to 1000 together with renaming KB to kB, right? |
Yes. That is my suggestion. |
|
No strong opinion on 1000-based vs 1024-based, but please use unit names consistent with what is chosen. |
|
I updated so the prefixes are unchanged (aside of of KB->kB as @hebasto suggested), and just the divisor is corrected from 1024 to 1000. |
|
Not sure if this |
src/qt/guiutil.cpp
Outdated
| if(bytes < 1024 * 1024 * 1024) | ||
| return QObject::tr("%1 MB").arg(bytes / 1024 / 1024); | ||
| if(bytes < 1000 * 1000) | ||
| return QObject::tr("%1 kB").arg(bytes / 1000); |
There was a problem hiding this comment.
@hebasto: This seems like a good place for some context to translators. For example, look at the French translation below.

I don't know how the decimal unit kB is written in French (Edit: It's written as ko), but how do we let a translator know that they are supposed to translate as thedecimal unit and not the binary unit?
There was a problem hiding this comment.
Yes. We could add more translation context later, when bitcoin/bitcoin#21465 approach is implemented.
src/qt/trafficgraphwidget.cpp
Outdated
| float inRate = (bytesIn - nLastBytesIn) * 1.0f / timer->interval(); | ||
| float outRate = (bytesOut - nLastBytesOut) * 1.0f / timer->interval(); |
There was a problem hiding this comment.
I am no C++ expert, just took it over from / 1024.0f * 1000 before. If the 1024.0f was also not needed (I imagined it might have had some reason of C++ type conversion), I will remove the * 1.0f
There was a problem hiding this comment.
If type conversion is supposed, it would better to apply explicit conversion.
src/qt/trafficgraphwidget.cpp
Outdated
| bytesOut = clientModel->node().getTotalBytesSent(); | ||
| float inRate = (bytesIn - nLastBytesIn) / 1024.0f * 1000 / timer->interval(); | ||
| float outRate = (bytesOut - nLastBytesOut) / 1024.0f * 1000 / timer->interval(); | ||
| // Rates are in bytes/millisecond which is equal to kilobytes/second |
There was a problem hiding this comment.
Instead of adding a comment, is it better just choose proper names for variables?
E.g., in_rate_kilobytes_per_sec ?
Thanks for the tipp, have done that, will update. |
|
May I suggest a change: --- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -759,14 +759,14 @@ QString formatNiceTimeOffset(qint64 secs)
QString formatBytes(uint64_t bytes)
{
- if (bytes < 1000)
+ if (bytes < 1'000)
return QObject::tr("%1 B").arg(bytes);
- if (bytes < 1000 * 1000)
- return QObject::tr("%1 kB").arg(bytes / 1000);
- if (bytes < 1000 * 1000 * 1000)
- return QObject::tr("%1 MB").arg(bytes / 1000 / 1000);
+ if (bytes < 1'000'000)
+ return QObject::tr("%1 kB").arg(bytes / 1'000);
+ if (bytes < 1'000'000'000)
+ return QObject::tr("%1 MB").arg(bytes / 1'000'000);
- return QObject::tr("%1 GB").arg(bytes / 1000 / 1000 / 1000);
+ return QObject::tr("%1 GB").arg(bytes / 1'000'000'000);
}
qreal calculateIdealFontSize(int width, const QString& text, QFont font, qreal minPointSize, qreal font_size) {
diff --git a/src/qt/trafficgraphwidget.cpp b/src/qt/trafficgraphwidget.cpp
index 9e0b67917..7e12410c8 100644
--- a/src/qt/trafficgraphwidget.cpp
+++ b/src/qt/trafficgraphwidget.cpp
@@ -128,8 +128,8 @@ void TrafficGraphWidget::updateRates()
quint64 bytesIn = clientModel->node().getTotalBytesRecv(),
bytesOut = clientModel->node().getTotalBytesSent();
- float in_rate_kilobytes_per_sec = (bytesIn - nLastBytesIn) / timer->interval();
- float out_rate_kilobytes_per_sec = (bytesOut - nLastBytesOut) / timer->interval();
+ float in_rate_kilobytes_per_sec = static_cast<float>(bytesIn - nLastBytesIn) / timer->interval();
+ float out_rate_kilobytes_per_sec = static_cast<float>(bytesOut - nLastBytesOut) / timer->interval();
vSamplesIn.push_front(in_rate_kilobytes_per_sec);
vSamplesOut.push_front(out_rate_kilobytes_per_sec);
nLastBytesIn = bytesIn;? It makes |
|
Thanks very much for the high quality coding hints! Updated commit. (and did a successfull local build on Debian Buster (Qt 5.11.3) and test run, too) |
|
@jonatack Do you mind looking into this PR? |
leonardojobim
left a comment
There was a problem hiding this comment.
Tested ACK d09ebc4 on Ubuntu 20.04 Qt 5.12.8
|
Additional discussion from IRC:
|
|
Concept ACK. Using powers of 10 and correctly calling them kB and MB seems reasonable for a user-facing GUI. |
…d "Bytes/s" with 1000-based prefix names use 1000-based divisor instead of 1024-based d09ebc4 Fix wrong(1024) divisor for 1000-based prefixes (wodry) Pull request description: v.0.21.0 I saw in the GUI peer window in the "received" column `1007 KB`, and after increasing to >=1024 I guess, it switched to `1 MB`. I would have expected the display unit to change from KB to MB already at value >=1000. I looked into the code, and the values appear to be power-of-2 byte values, so the switching at >=1024 and not >=1000 seems correct. But the unit display is not precisely correct, binary prefixes should be used for power-of-2 byte values. To be correct, this PR changes ~~KB/MB/GB to KiB/MiB/GiB.~~ KB to kB and the divisor from 1024 to 1000. ACKs for top commit: hebasto: ACK d09ebc4, tested on Linux Mint 20.1 (Qt 5.12.8) the both "Network Traffic" and "Peers" tabs of the "Node Window". jarolrod: ACK d09ebc4 leonardojobim: Tested ACK bitcoin-core/gui@d09ebc4 on Ubuntu 20.04 Qt 5.12.8 Tree-SHA512: 8f830b08cc3fd36dc8a18f1192959fe55d1644938044bf31d770f7c3bf8475fba6da5019a2d2024d5b2c81a8dab112f360c555367814a14f4d05c89d130f25b0




v.0.21.0
I saw in the GUI peer window in the "received" column
1007 KB, and after increasing to >=1024 I guess, it switched to1 MB. I would have expected the display unit to change from KB to MB already at value >=1000.I looked into the code, and the values appear to be power-of-2 byte values, so the switching at >=1024 and not >=1000 seems correct.
But the unit display is not precisely correct, binary prefixes should be used for power-of-2 byte values.
To be correct, this PR changes
KB/MB/GB to KiB/MiB/GiB.KB to kB and the divisor from 1024 to 1000.