rational.c 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. /*
  2. * rational fractions
  3. *
  4. * Copyright (C) 2009 emlix GmbH, Oskar Schirmer <os@emlix.com>
  5. *
  6. * helper functions when coping with rational numbers
  7. */
  8. #include <linux/rational.h>
  9. #include <linux/module.h>
  10. /*
  11. * calculate best rational approximation for a given fraction
  12. * taking into account restricted register size, e.g. to find
  13. * appropriate values for a pll with 5 bit denominator and
  14. * 8 bit numerator register fields, trying to set up with a
  15. * frequency ratio of 3.1415, one would say:
  16. *
  17. * rational_best_approximation(31415, 10000,
  18. * (1 << 8) - 1, (1 << 5) - 1, &n, &d);
  19. *
  20. * you may look at given_numerator as a fixed point number,
  21. * with the fractional part size described in given_denominator.
  22. *
  23. * for theoretical background, see:
  24. * http://en.wikipedia.org/wiki/Continued_fraction
  25. */
  26. void rational_best_approximation(
  27. unsigned long given_numerator, unsigned long given_denominator,
  28. unsigned long max_numerator, unsigned long max_denominator,
  29. unsigned long *best_numerator, unsigned long *best_denominator)
  30. {
  31. unsigned long n, d, n0, d0, n1, d1;
  32. n = given_numerator;
  33. d = given_denominator;
  34. n0 = d1 = 0;
  35. n1 = d0 = 1;
  36. for (;;) {
  37. unsigned long t, a;
  38. if ((n1 > max_numerator) || (d1 > max_denominator)) {
  39. n1 = n0;
  40. d1 = d0;
  41. break;
  42. }
  43. if (d == 0)
  44. break;
  45. t = d;
  46. a = n / d;
  47. d = n % d;
  48. n = t;
  49. t = n0 + a * n1;
  50. n0 = n1;
  51. n1 = t;
  52. t = d0 + a * d1;
  53. d0 = d1;
  54. d1 = t;
  55. }
  56. *best_numerator = n1;
  57. *best_denominator = d1;
  58. }
  59. EXPORT_SYMBOL(rational_best_approximation);