Signed-off-by: Alexandre Ratchov Index: e2fsprogs-1.39/lib/e2p/percent.c =================================================================== --- e2fsprogs-1.39.orig/lib/e2p/percent.c 2006-09-20 12:07:05.000000000 +0200 +++ e2fsprogs-1.39/lib/e2p/percent.c 2006-09-20 12:36:32.000000000 +0200 @@ -7,25 +7,50 @@ * Public License */ +/* #include "e2p.h" +*/ #include /* * We work really hard to calculate this accurately, while avoiding * an overflow. "Is there a hyphen in anal-retentive?" :-) + * + * -- "Yes there is, as in hair-splitting and nit-picking" */ unsigned int e2p_percent(int percent, unsigned int base) { - unsigned int mask = ~((1 << (sizeof(unsigned int) - 1) * 8) - 1); + unsigned hi, lo, q, r; - if (100 % percent == 0) - return base / (100 / percent); - if (mask & base) - return (base / 100) * percent; - return base * percent / 100; + /* + * in order to avoid overflow we write 'base' as: + * + * base = hi * 2^16 + lo + * + * then we do all computations separately on 'hi' and 'lo'. + * By using the definition of division: + * + * precent * base = result * 100 + reminder + * + * (reminder < 100), we obtain the exact value of 'result' + * as follows: + */ +#define BITS 16 +#define MASK ((1 << BITS) - 1) + + hi = percent * (base >> BITS); + lo = percent * (base & MASK); + + q = ((hi / 100) << BITS) + lo / 100; + r = ((hi % 100) << BITS) + lo % 100; + + return q + r / 100; +#undef BITS +#undef MASK } + #ifdef DEBUG #include #include