fix __div64_32 to do division properly
PATCH 1/1 fix __div64_32 to do division properly
The generic __div64_32 in lib/div64.c only handles "small" divisors. If the divisor is full 32-bits, it returns invalid results. This patch fixes it. (this is used e.g. in nanosleep)
thanks
randolph
Index: lib/div64.c
===================================================================
RCS file: /var/cvs/linux-2.6/lib/div64.c,v
retrieving revision 1.1
div64.c +18 -16
@@ -25,25 +25,27 @@uint32_t __div64_32 (uint64_t *n,uint32_t base) { -uint32_t low, low2, high, rem; +uint64_t rem = *n; +uint64_t b = base; +uint64_t res =0 , d =1 ; - low = *n &0xffffffff ; - high = *n >>32 ; - rem = high % (uint32_t )base; - high = high / (uint32_t )base; - low2 = low >>16 ; - low2 += rem <<16 ; - rem = low2 % (uint32_t )base; - low2 = low2 / (uint32_t )base; - low = low &0xffff ; - low += rem <<16 ; - rem = low % (uint32_t )base; - low = low / (uint32_t )base; +if (b >0 ) { +while (b < rem) { + b <<=1 ; + d <<=1 ; + } + } - *n = low + - ((uint64_t )low2 <<16 ) + - ((uint64_t )high <<32 ); +do { +if (rem >= b) { + rem -= b; + res += d; + } + b >>=1 ; + d >>=1 ; + }while (d); + *n = res;return rem; }
Signature · 3 lines
Randolph Chung Debian GNU/Linux Developer, hppa/ia64 ports http://www.tausq.org/