blob: 6d35274170bcd6c85fa56a0b92e5696d310f7273 [file] [log] [blame]
Davidlohr Bueso30493cc2013-04-29 16:18:09 -07001/*
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 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07007
8#include <linux/kernel.h>
Paul Gortmaker8bc3bcc2011-11-16 21:29:17 -05009#include <linux/export.h>
Peter Zijlstra627f9c32017-11-17 15:28:08 -080010#include <linux/bitops.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070011
12/**
13 * int_sqrt - rough approximation to sqrt
14 * @x: integer of which to calculate the sqrt
15 *
16 * A very rough approximation to the sqrt() function.
17 */
18unsigned long int_sqrt(unsigned long x)
19{
Davidlohr Bueso30493cc2013-04-29 16:18:09 -070020 unsigned long b, m, y = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -070021
Davidlohr Bueso30493cc2013-04-29 16:18:09 -070022 if (x <= 1)
23 return x;
Linus Torvalds1da177e2005-04-16 15:20:36 -070024
Peter Zijlstra627f9c32017-11-17 15:28:08 -080025 m = 1UL << (__fls(x) & ~1UL);
Davidlohr Bueso30493cc2013-04-29 16:18:09 -070026 while (m != 0) {
27 b = y + m;
28 y >>= 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -070029
Davidlohr Bueso30493cc2013-04-29 16:18:09 -070030 if (x >= b) {
31 x -= b;
32 y += m;
Linus Torvalds1da177e2005-04-16 15:20:36 -070033 }
Davidlohr Bueso30493cc2013-04-29 16:18:09 -070034 m >>= 2;
Linus Torvalds1da177e2005-04-16 15:20:36 -070035 }
Davidlohr Bueso30493cc2013-04-29 16:18:09 -070036
37 return y;
Linus Torvalds1da177e2005-04-16 15:20:36 -070038}
39EXPORT_SYMBOL(int_sqrt);