5 ms·
Rounding Percentages
- pmw 2y agoNot sure how much I like this. With this algorithm, the user would never see 100% displayed, because at that point the UI would change to remove the progress bar entirely. Whereas seeing 100% feels oddly satisfying, even if inaccurate.
- kortex 2y agoMany TUIs (text user interface) with multiple operations will show one bar reach 100% and move onto the next process (or show multiple in parallel). If the UI automatically transitions to a totally new screen after completion, I'm never going to see 100% anyways, unless the app does the exact infuriating thing in TFA, which is render 100% (at 99.whatever) and then do some fsync/cleanup and actually be frozen showing 100% which is the contrapositive of oddly satisfying, it's unsurprisingly unsatisfying.
- chriscjcj 2y agoI agree with Tavian Barnes' arguments 110%.
- ajuc 2y ago> Is it actually done? Or did it download 999/1000 bytes and then hang? The label on the progress bar should be "12345 out of 23456 files copied" and not 53% for this reason. That way you can see if it hanged even if the progress is very slow. Besides - the percentage label is redundant - the bar shows it graphically anyway.
- deleted 2y ago[deleted]
- silvestrov 2y agoProblem is the rounding in the text: 12.1 MB of 12.1 MB downloaded. You can't see if this is 99% or not. All digits even become difficult with large numbers: 175.464.272 of 175.484.272 downloaded (i.e. not 100%).
- hunter2_ 2y agoHow about "N remaining"? Anything that isn't zero means it's still in progress or stalled. Only abbreviate (via thousands indicators like K, M, G, etc.) when it actually shortens the text meaningfully, so there will be no truncation or rounding toward the end.
- michaelmior 2y agoDepending on the audience, it could be confusing if you're changing units.
- nritchie 2y agoHow about "Pending" and "Complete" for 0% and 100%?
- threatripper 2y agoI just got reminded that round(0.5) is poorly defined across different languages and your results may vary if you use this algorithm without properly understanding what round() does in your language vs. what is expected by the algorithm.
- lifthrasiir 2y agoIt is especially ill-defined when the input itself may have been rounded already, e.g. round(0.15, 1) = 0.1 because 0.15 is not exact in binary64 and the binary64 value closest to 0.15 is a bit smaller than 0.15. If you have to retain the exact rounded value for some reason, you should switch to fixed point from that point on.
- deleted 2y ago[deleted]
- shhsshs 2y ago> If your language has bad defaults, you may have to ask for the right rounding mode explicitly. Is the author implying Rust's default rounding behavior is a bad default? In what world is "ties to even" a GOOD default?
- alkonaut 2y agoThe motivation for the seemingly strange rounding is that a set of numbers can be rounded before summing without biasing the sum. It has good use cases but so do all rounding modes.
- wizerno 2y agoIt's also called banker's rounding. To understand why it's a good default, you can check out https://mathematica.stackexchange.com/a/2120 https://mathematica.stackexchange.com/a/2120
- tavianator 2y agoIn general, if some recommendation from IEEE 754 (the floating-point standard) seems strange, its because someone like William Kahan thought about it in great detail and you'd be wise to follow it. https://en.wikipedia.org/wiki/Rounding#Rounding_half_to_even https://en.wikipedia.org/wiki/Rounding#Rounding_half_to_even
- AnotherGoodName 2y agoA good rule is that showing progress or a stuck state appropriately at all stages takes precedence over other concerns in a progress bar. So for a video upload from a photo app it's not at all unreasonable to make the first 50% the transcoding step and the second 50% the actual upload and show progress of each step within those percentages. Some people may read this with horror; the transcoding step might be much faster/slower! It's not accurate! But the point is the user can at least see progress/no progress. You aren't allowing an upload bar to sit at 0% because you prioritised a % accurate upload over a progress bar that represents all stages of progress. It's better the progress bar move faster/slower at various stages than a progress bar that simply misses stages. This goes for loading screens that sit at 100% for a while too. I'd prefer if they reserved some percentage of the loading bar for those 'post 100%' steps and continued to show progress. End users won't care if it's not all the same speed as much as they'll care about stuck progress bars.
- chatmasta 2y agoIf you can cleanly segment the loading progress into multiple steps, you may as well render a label above the loading bar that says what it’s currently doing.
- AnotherGoodName 2y agoWe're often limited to showing progress on a percentage bar UX wise for various reasons, particularly on mobile devices. I'd also give thought that each technical step may as well read something similar to 'reticulating splines' as far as an end user is concerned.
- mewpmewp2 2y agoUsually even technical terms are interesting since you have to wait anyway. Makes your imagination go. Unfortunately it is much rarer nowadays and everything is hidden away.
- leansensei 2y ago
- moonchild 2y ago> float hm ... >>> def percent(progress, total): ... return round(99 * progress / total + 0.5) ... >>> x = 9007199254740990.0 >>> x - 1 < x True >>> percent(x - 1, x) 100
- tavianator 2y agoYou're cheating by using floating-point arguments; they should be integers: >>> x = 9007199254740990 >>> percent(x - 1, x) 99 But then again, >>> percent(10 * x - 1, 10 * x) 100 If your procedure has 2^53 steps, feel free to ignore my rounding recommendations, since I'll never see it get anywhere near 100% :) Also if your username is named after the band, good taste :)
- moonchild 2y ago> they should be integers i am not cheating; you are cheating by trying to do integer arithmetic instead of float arithmetic. in particular: 99 * progress is a (potentially big) integer; then the quotient, from my understanding of python, is equal to the mathematical quantity rn(99 * progress / total), which is not trivial to compute. (although cpython does tend to do a particularly bad job of this sort of thing.) (compare with c or with my version of the python, where it would be rn(rn(99 * progress) / rn(total)), rounding twice, which is very easy to compute. i'm not saying the c semantics is better, mind.) when you scale up by 10x, the numerator is <1/2 'ulp' away from the denominator, and so the quotient rounds up to 99 exactly; there is still double rounding (would have been triple rounding in c and my python), because we got rn(rn(99 * progress / total) + 0.5) where what we wanted was rn(99 * progress / total + 0.5) (which is mathematically always the correct result) i agree it is not common to have so many steps. but if i were providing a routine that was intended to be robust where others were not, i would try to be comprehensive. and i would not try to do int math with floats unless i could show it to be robust (i have sketched such a stunt! https://gist.github.com/moon-chilled/60bd2ba687dc197d93a9d2251229d715 https://gist.github.com/moon-chilled/60bd2ba687dc197d93a9d22...). the integer routine is simpler and more honest anyway, and it is obvious that it works uniformly for the entire range note also that, with x floating, the python expressions 10 * x and 10 * x - 1 are equivalent, meaning the error is on input to the percent function. (if we set progress to 10 * x - 8, the immediately preceding fp number, we do get 99, but there is no deep reason for this, and it differs for different values of 10.) > if your username is named after the band, good taste :) my username comes from a book: the neverending story. i am more using the german version of the name these days but i do not feel like making a new account on this godforesaken website
- drpixie 2y agoAnd a really bad example - apps from a certain large search/email/ad company where the progress bar moves even when nothing is actually happening ;(
- kangalioo 2y agoI'm afraid this introduces too much magic Personally, "0%" doesn't mean "hasn't started" to me, it means "not enough progress has happened to reach 1%". Assuming I'm not alone with that, the rounding becomes a simple truncation `roundedPercent = int(percent)` An implementation as simple as the concept, which is a good sign in my experience
- graypegg 2y agoA little while ago, an article about a “plan-execute pattern” came up, feels like a clean fit to better progress bars to me! I think the most annoying thing is definitely when only 1 part of the process is represented in the progress bar, like a video upload that only shows upload progress, but not the transcoding that happens after. Feels like having some standard plan + execution status interface would at least force you to consider a whole process even if that multistep plan is basically hardcoded. https://news.ycombinator.com/item?id=40749401 https://news.ycombinator.com/item?id=40749401
- teknopaul 2y agoTo solve this problem recently, I just defined -1% as 'not at all' and 101% as 'all of it' . But then, I'm a Unix hacker. ;)