blob: 1afb545a37c5e36fedfd8e3872922c04c658abdf [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>
Linus Torvalds1da177e2005-04-16 15:20:36 -070010
11/**
12 * int_sqrt - rough approximation to sqrt
13 * @x: integer of which to calculate the sqrt
14 *
15 * A very rough approximation to the sqrt() function.
16 */
17unsigned long int_sqrt(unsigned long x)
18{
Davidlohr Bueso30493cc2013-04-29 16:18:09 -070019 unsigned long b, m, y = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -070020
Davidlohr Bueso30493cc2013-04-29 16:18:09 -070021 if (x <= 1)
22 return x;
Linus Torvalds1da177e2005-04-16 15:20:36 -070023
Davidlohr Bueso30493cc2013-04-29 16:18:09 -070024 m = 1UL << (BITS_PER_LONG - 2);
Peter Zijlstrae6008a02017-11-17 15:28:04 -080025 while (m > x)
26 m >>= 2;
27
Davidlohr Bueso30493cc2013-04-29 16:18:09 -070028 while (m != 0) {
29 b = y + m;
30 y >>= 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -070031
Davidlohr Bueso30493cc2013-04-29 16:18:09 -070032 if (x >= b) {
33 x -= b;
34 y += m;
Linus Torvalds1da177e2005-04-16 15:20:36 -070035 }
Davidlohr Bueso30493cc2013-04-29 16:18:09 -070036 m >>= 2;
Linus Torvalds1da177e2005-04-16 15:20:36 -070037 }
Davidlohr Bueso30493cc2013-04-29 16:18:09 -070038
39 return y;
Linus Torvalds1da177e2005-04-16 15:20:36 -070040}
41EXPORT_SYMBOL(int_sqrt);