Merge tag 'for-linus-5.14-ofs1' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / lib / math / rational.c
index 9781d52..c0ab51d 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/compiler.h>
 #include <linux/export.h>
 #include <linux/minmax.h>
+#include <linux/limits.h>
 
 /*
  * calculate best rational approximation for a given fraction
@@ -78,13 +79,18 @@ void rational_best_approximation(
                 * found below as 't'.
                 */
                if ((n2 > max_numerator) || (d2 > max_denominator)) {
-                       unsigned long t = min((max_numerator - n0) / n1,
-                                             (max_denominator - d0) / d1);
+                       unsigned long t = ULONG_MAX;
 
-                       /* This tests if the semi-convergent is closer
-                        * than the previous convergent.
+                       if (d1)
+                               t = (max_denominator - d0) / d1;
+                       if (n1)
+                               t = min(t, (max_numerator - n0) / n1);
+
+                       /* This tests if the semi-convergent is closer than the previous
+                        * convergent.  If d1 is zero there is no previous convergent as this
+                        * is the 1st iteration, so always choose the semi-convergent.
                         */
-                       if (2u * t > a || (2u * t == a && d0 * dp > d1 * d)) {
+                       if (!d1 || 2u * t > a || (2u * t == a && d0 * dp > d1 * d)) {
                                n1 = n0 + t * n1;
                                d1 = d0 + t * d1;
                        }