aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/int_sqrt.c32
1 files changed, 19 insertions, 13 deletions
diff --git a/lib/int_sqrt.c b/lib/int_sqrt.c
index fc2eeb7cb2ea..1ef4cc344977 100644
--- a/lib/int_sqrt.c
+++ b/lib/int_sqrt.c
@@ -1,3 +1,9 @@
1/*
2 * Copyright (C) 2013 Davidlohr Bueso <davidlohr.bueso@hp.com>
3 *
4 * Based on the shift-and-subtract algorithm for computing integer
5 * square root from Guy L. Steele.
6 */
1 7
2#include <linux/kernel.h> 8#include <linux/kernel.h>
3#include <linux/export.h> 9#include <linux/export.h>
@@ -10,23 +16,23 @@
10 */ 16 */
11unsigned long int_sqrt(unsigned long x) 17unsigned long int_sqrt(unsigned long x)
12{ 18{
13 unsigned long op, res, one; 19 unsigned long b, m, y = 0;
14 20
15 op = x; 21 if (x <= 1)
16 res = 0; 22 return x;
17 23
18 one = 1UL << (BITS_PER_LONG - 2); 24 m = 1UL << (BITS_PER_LONG - 2);
19 while (one > op) 25 while (m != 0) {
20 one >>= 2; 26 b = y + m;
27 y >>= 1;
21 28
22 while (one != 0) { 29 if (x >= b) {
23 if (op >= res + one) { 30 x -= b;
24 op = op - (res + one); 31 y += m;
25 res = res + 2 * one;
26 } 32 }
27 res /= 2; 33 m >>= 2;
28 one /= 4;
29 } 34 }
30 return res; 35
36 return y;
31} 37}
32EXPORT_SYMBOL(int_sqrt); 38EXPORT_SYMBOL(int_sqrt);