This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit db5cb4a54faeed378e762315f864692f8563063e
Author: Marco Casaroli <[email protected]>
AuthorDate: Mon Oct 19 02:29:59 2026 +0200

    libs/libm: Fix the endless loop in logl().
    
    logl() repeats a Newton step until the change is less than
    LDBL_EPSILON times the result.  For some arguments the steps do not get
    that small, and logl() never returns.  For example, 
logl(0x1.61192641b328cp+0)
    does not return when long double has the format of double.
    
    Relax the limit after every 400 steps, as log() and logf() do.
    
    Assisted-by: Claude Code:claude-opus-5-5
    Signed-off-by: Marco Casaroli <[email protected]>
---
 libs/libm/libm/lib_logl.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/libs/libm/libm/lib_logl.c b/libs/libm/libm/lib_logl.c
index c41124f74f6..bbab8cc4760 100644
--- a/libs/libm/libm/lib_logl.c
+++ b/libs/libm/libm/lib_logl.c
@@ -40,6 +40,13 @@
 
 #define LDBL_MAX_EXP_X  700.0
 
+/* Like log(): relax the error criteria by LOGL_RELAX_MULTIPLIER after every
+ * LOGL_MAX_ITER iterations, to avoid looping forever.
+ */
+
+#define LOGL_MAX_ITER         400
+#define LOGL_RELAX_MULTIPLIER 2.0L
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -51,11 +58,16 @@ long double logl(long double x)
   long double y_old;
   long double ey;
   long double epsilon;
+  long double rf;
+  int iter;
 
   y = 0.0;
   y_old = 1.0;
   epsilon = LDBL_EPSILON;
 
+  iter = 0;
+  rf = 1.0L;
+
   while (y > y_old + epsilon || y < y_old - epsilon)
     {
       y_old = y;
@@ -72,7 +84,13 @@ long double logl(long double x)
           y = -LDBL_MAX_EXP_X;
         }
 
-      epsilon = (fabsl(y) > 1.0) ? fabsl(y) * LDBL_EPSILON : LDBL_EPSILON;
+      epsilon = ((fabsl(y) > rf) ? fabsl(y) : rf) * LDBL_EPSILON;
+
+      if (++iter >= LOGL_MAX_ITER)
+        {
+          rf *= LOGL_RELAX_MULTIPLIER;
+          iter = 0;
+        }
     }
 
   if (y == LDBL_MAX_EXP_X)

Reply via email to