rational.c 1.5 KB

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