Summary: | Filesize rounding and significant digits... | ||
---|---|---|---|
Product: | [Frameworks and Libraries] kdelibs | Reporter: | Bzzz <misc-kdeorg> |
Component: | klocale | Assignee: | Chusslove Illich <caslav.ilic> |
Status: | REPORTED --- | ||
Severity: | wishlist | CC: | cfeck, frank78ac, jlayt |
Priority: | NOR | ||
Version: | 4.9.5 | ||
Target Milestone: | --- | ||
Platform: | Ubuntu | ||
OS: | Linux | ||
Latest Commit: | Version Fixed In: | ||
Attachments: | conversion demo script |
Description
Bzzz
2013-01-05 02:55:48 UTC
Thanks for the detailed report. This isn't a Dolphin issue, the formatting of file sizes is done by KLocale::formatByteSize(): http://api.kde.org/4.x-api/kdelibs-apidocs/kdecore/html/classKLocale.html#a3116ebc59ad98cbf80dc06ff9489e330 > Yes, I know there are more important things to fix! ;) Yes indeed ;-) Nobody else ever complained about this AFAIK, so I think the only way to change the behaviour in the near future might be that you dig into the code and submit a kdelibs patch to ReviewBoard. Interestingly, I to have been annoyed by this behavior and for exactly the reason Bzzz states, but never sufficently annoyed to start a discussion about it. (Maybe because when I really need to make size-based decisions, I usually revert to du and explicit unit selection...). I can only say I'd be all in favor of the change, and I'm adding current maintainer of KLocale to CC list. I really wished there was an option to "spoil the fun" and just display the exact number of bytes, thousands separated by spaces, so that you can easily see the magnitude. It looks like Dolphin uses the default formatByteSize() method which defaults to 1 decimal place and the default algorithm described below, rather than newer api which allows you to set the required significant digits and units to use (http://api.kde.org/4.x-api/kdelibs-apidocs/kdecore/html/classKLocale.html#a566a3d868abfca050e1191b16e85ed73). Perhaps a quick initial fix will be for Dolphin to define 2 decimal places? Here's a simplified version of the current code: QString KLocalePrivate::formatByteSize(double bytes, int precision, BinaryUnitDialect dialect, BinarySizeUnits units) { double value = bytes int magnitude = 0; double multiplier = 1024.0; if (dialect == MetricBinaryDialect) { multiplier = 1000.0; } if (units == DefaultBinaryUnits) { while (value >= multiplier && magnitude < maxMagnitude) { value = value / multiplier; magnitude = magnitude + 1; } } else { magnitude = units; if (magnitude > 0) { value = value / pow(multiplier, magnitude); } } if (magnitude == 0) { // Bytes, no rounding numString = formatNumber(values, 0); } else { numString = formatNumber(value, precision); } return translateUnits(dialect, magnitude, numString); } There are two key points to the algorithm: * If the base units, i.e. bytes < multiplier, then the precision is ignored, i.e. no decimal places * It moves up to the next magnitude once it goes over the magnitude, and not before The question is, under what conditions do you decide to go to the next magnitude of units, 1% before, 5% before? And does having a decimal place on the bytes make any logical sense when it will always be .0? What works in some uses will not be suitable for others, i.e. a single value in the middle of a sentence versus a list view in Dolphin, and the default has to try cater for the most common use case, leaving special cases to write their own code using the advanced api. I also am reluctant to change the current default behaviour as many other apps could be depending on the way it currently works. You also have to remember that Dolphin is designed as a simpler style of file manager for 90% of use cases, any solution would need to target most users, and in most cases a rough idea of file size is all that is needed. I'm a little unclear on the exact behaviour you'd prefer, if you could write a simple algorithm in words for how you think it should behave? Perhaps Dolphin could then implement the algorithm itself for its particular use case, or we could extend the api to allow the behaviour to be controlled? (In reply to comment #4) > The question is, under what conditions do you decide to go to the next > magnitude of units, 1% before, 5% before? As soon as it reaches the fourth place before the decimal point/comma. Because we use 2^10 counts until we switch units, that cannot be a fixed percentage (as percentage uses a system based on 10^x). I guess that has to be 1 - (1000/1024)^x, with x being magnitude, e.g. 1 for bytes, 2 for Kibibytes, and so on. That calculates the difference between any binary and decimal unit. For example, 1 Gibibyte has 1,073,741,824 bytes. The condition needs to be in effect at 1,000,000,000 bytes, while 999,999,999 is still okay. 1-(1000/1024)^3 equals 0.93132.., multiplied with 1 GiB that is exactly 1,000,000,000 Bytes or 1 GB. So in this case, it would be 6,868..% before the current switching point. But I think it is easier to implement something that just uses the next magnitude when reaching a certain number of digits, because all of these changes happen at 1+3y digits (y=1 for 1000, y=2 for 1000000, and so on) > And does having a decimal place > on the bytes make any logical sense when it will always be .0? For quantities of just bytes, that is below 1024 bytes, the .0 doesn't make sense (I think I said that), as there is no fraction of a byte. For any larger numbers, the decimal place does make sense. > I'm a little unclear on the exact behaviour you'd prefer, if you could write > a simple algorithm in words for how you think it should behave? I'll try that asap > Perhaps > Dolphin could then implement the algorithm itself for its particular use > case, or we could extend the api to allow the behaviour to be controlled? As you said, other programs might depend on the current implementation. Therefore an API extension would be the best way to deal with that, without breaking other code. Created attachment 76797 [details]
conversion demo script
Guess I was wrong in determining the point where to switch units. Of course one can use for example 999 (instead of 931) GiB before the unit has to be TiB. It's just that the TiB numbering won't start at 1.00, but rather at 0.9somewhat TiB.
Well, first code proposal is the following one. Note that it doesn't really make use of the const maxdigits, so atm output is fixed to three digits (I know that 0.9x to 0.99 has not three significant figures like any other number above 1 and below 999, but I think that is a reasonable compromise to keep things simple). Implementing this would allow for two additional fine-tuning options:
* granularity: numbers like 0.9939 TiB (more digits) or 0.1 GiB, 1,0 GiB, 10 GiB, 0.1 TiB (less digits)
* Like Christoph Feck proposed, larger amounts before switching units, like 9999 MiB -> MiB overflow -> 9,766 GiB, 99,99GiB, 999,9GiB, 9999GiB -> GiB overflow ->, including the extremal setting of never even leaving the Byte unit and therefore displaying any given filesize in bytes.
|