int_sqrt.c 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2013 Davidlohr Bueso <[email protected]>
  4. *
  5. * Based on the shift-and-subtract algorithm for computing integer
  6. * square root from Guy L. Steele.
  7. */
  8. #include <linux/export.h>
  9. #include <linux/bitops.h>
  10. #include <linux/limits.h>
  11. #include <linux/math.h>
  12. /**
  13. * int_sqrt - computes the integer square root
  14. * @x: integer of which to calculate the sqrt
  15. *
  16. * Computes: floor(sqrt(x))
  17. */
  18. unsigned long int_sqrt(unsigned long x)
  19. {
  20. unsigned long b, m, y = 0;
  21. if (x <= 1)
  22. return x;
  23. m = 1UL << (__fls(x) & ~1UL);
  24. while (m != 0) {
  25. b = y + m;
  26. y >>= 1;
  27. if (x >= b) {
  28. x -= b;
  29. y += m;
  30. }
  31. m >>= 2;
  32. }
  33. return y;
  34. }
  35. EXPORT_SYMBOL(int_sqrt);
  36. #if BITS_PER_LONG < 64
  37. /**
  38. * int_sqrt64 - strongly typed int_sqrt function when minimum 64 bit input
  39. * is expected.
  40. * @x: 64bit integer of which to calculate the sqrt
  41. */
  42. u32 int_sqrt64(u64 x)
  43. {
  44. u64 b, m, y = 0;
  45. if (x <= ULONG_MAX)
  46. return int_sqrt((unsigned long) x);
  47. m = 1ULL << ((fls64(x) - 1) & ~1ULL);
  48. while (m != 0) {
  49. b = y + m;
  50. y >>= 1;
  51. if (x >= b) {
  52. x -= b;
  53. y += m;
  54. }
  55. m >>= 2;
  56. }
  57. return y;
  58. }
  59. EXPORT_SYMBOL(int_sqrt64);
  60. #endif