Lately at work, we were wondering how to compute a simple progress value (let's
say for a download in our case). We have in input a float
value in the range
[0.0;100.0]
, and we want to display the percent in integer
(it's generally
handy if we want to reuse it when dealing with pixels). The quick and dirty
method would be:
return (int)v;
or if you want some rounding:
return (int)(v+.5f);
But this is sometimes not enough. Indeed, we would like to make a distinction between a download of a big file that has just started, and a download stalled at 0% with not a single byte received. And in the same time, we don't want a near-the-end download at 99.9% considered done.
Here is my current solution:
return (int)v + !(int)v - !v;
and with the comments:
#include <stdio.h>
#define P(v) printf("v=%-6.1f p=%d\n", v, p(v))
int p(float v) { return (int)v + !(int)v - !v; }
// intbase + range01 - iszero = p
int main() { // (int)v !(int)v !v
P(0.); // 0 + 1 - 1 = 0
P(0.3); // 0 + 1 - 0 = 1
P(0.7); // 0 + 1 - 0 = 1
P(1.1); // 1 + 0 - 0 = 1
P(1.5); // 1 + 0 - 0 = 1
P(21.1); // 21 + 0 - 0 = 21
P(31.6); // 31 + 0 - 0 = 31
P(99.3); // 99 + 0 - 0 = 99
P(99.7); // 99 + 0 - 0 = 99
P(100.); // 100 + 0 - 0 = 100
return 0;
}
This is enough for our case, but you may want to add a rounding level. You can, but it gets complicated pretty quickly (for not much benefit), especially if you want to avoid ternary.