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 1685e027c068a81901da308869a706f07b4b7a01
Author: Marco Casaroli <[email protected]>
AuthorDate: Mon Oct 19 02:30:00 2026 +0200

    libs/libm: Add nearbyint(), lrint() and llrint().
    
    math.h declares nearbyint(), lrint(), llrint() and their float and long
    double versions, but the built-in libm did not have them.  Only the
    ARMv8-M FPU code had nearbyint() and nearbyintf().
    
    nearbyint() adds and subtracts 1 / EPSILON (2^52 for double), which
    rounds to an integer in the current rounding mode.  lrint() and llrint()
    convert the result of nearbyint().  The generic nearbyint() and
    nearbyintf() are not built when CONFIG_LIBM_ARCH_NEARBYINT(F) selects
    the ARMv8-M versions.
    
    Assisted-by: Claude Code:claude-opus-5-5
    Signed-off-by: Marco Casaroli <[email protected]>
---
 libs/libm/libm/CMakeLists.txt   | 17 ++++++++++-
 libs/libm/libm/Make.defs        | 10 +++++++
 libs/libm/libm/lib_llrint.c     | 41 ++++++++++++++++++++++++++
 libs/libm/libm/lib_llrintf.c    | 36 +++++++++++++++++++++++
 libs/libm/libm/lib_llrintl.c    | 41 ++++++++++++++++++++++++++
 libs/libm/libm/lib_lrint.c      | 41 ++++++++++++++++++++++++++
 libs/libm/libm/lib_lrintf.c     | 36 +++++++++++++++++++++++
 libs/libm/libm/lib_lrintl.c     | 41 ++++++++++++++++++++++++++
 libs/libm/libm/lib_nearbyint.c  | 65 +++++++++++++++++++++++++++++++++++++++++
 libs/libm/libm/lib_nearbyintf.c | 60 +++++++++++++++++++++++++++++++++++++
 libs/libm/libm/lib_nearbyintl.c | 65 +++++++++++++++++++++++++++++++++++++++++
 11 files changed, 452 insertions(+), 1 deletion(-)

diff --git a/libs/libm/libm/CMakeLists.txt b/libs/libm/libm/CMakeLists.txt
index db8ba65cc6d..b1da10ee3f5 100644
--- a/libs/libm/libm/CMakeLists.txt
+++ b/libs/libm/libm/CMakeLists.txt
@@ -150,7 +150,14 @@ if(CONFIG_LIBM)
       __cos.c
       __sin.c
       lib_gamma.c
-      lib_lgamma.c)
+      lib_lgamma.c
+      lib_lrint.c
+      lib_lrintf.c
+      lib_lrintl.c
+      lib_llrint.c
+      lib_llrintf.c
+      lib_llrintl.c
+      lib_nearbyintl.c)
 
   # Use the C versions of some functions only if architecture specific 
optimized
   # versions are not provided.
@@ -163,6 +170,10 @@ if(CONFIG_LIBM)
     list(APPEND SRCS lib_floor.c)
   endif()
 
+  if(NOT CONFIG_LIBM_ARCH_NEARBYINT)
+    list(APPEND SRCS lib_nearbyint.c)
+  endif()
+
   if(NOT CONFIG_LIBM_ARCH_RINT)
     list(APPEND SRCS lib_rint.c)
   endif()
@@ -183,6 +194,10 @@ if(CONFIG_LIBM)
     list(APPEND SRCS lib_floorf.c)
   endif()
 
+  if(NOT CONFIG_LIBM_ARCH_NEARBYINTF)
+    list(APPEND SRCS lib_nearbyintf.c)
+  endif()
+
   if(NOT CONFIG_LIBM_ARCH_RINTF)
     list(APPEND SRCS lib_rintf.c)
   endif()
diff --git a/libs/libm/libm/Make.defs b/libs/libm/libm/Make.defs
index a0947f47487..0196b8dc32b 100644
--- a/libs/libm/libm/Make.defs
+++ b/libs/libm/libm/Make.defs
@@ -57,6 +57,8 @@ CSRCS += lib_fmax.c lib_fmaxf.c lib_fmaxl.c
 CSRCS += lib_fmin.c lib_fminf.c lib_fminl.c
 
 CSRCS += __cos.c __sin.c lib_gamma.c lib_lgamma.c
+CSRCS += lib_lrint.c lib_lrintf.c lib_lrintl.c
+CSRCS += lib_llrint.c lib_llrintf.c lib_llrintl.c lib_nearbyintl.c
 
 # Use the C versions of some functions only if architecture specific
 # optimized versions are not provided.
@@ -69,6 +71,10 @@ ifneq ($(CONFIG_LIBM_ARCH_FLOOR),y)
 CSRCS += lib_floor.c
 endif
 
+ifneq ($(CONFIG_LIBM_ARCH_NEARBYINT),y)
+CSRCS += lib_nearbyint.c
+endif
+
 ifneq ($(CONFIG_LIBM_ARCH_RINT),y)
 CSRCS += lib_rint.c
 endif
@@ -89,6 +95,10 @@ ifneq ($(CONFIG_LIBM_ARCH_FLOORF),y)
 CSRCS += lib_floorf.c
 endif
 
+ifneq ($(CONFIG_LIBM_ARCH_NEARBYINTF),y)
+CSRCS += lib_nearbyintf.c
+endif
+
 ifneq ($(CONFIG_LIBM_ARCH_RINTF),y)
 CSRCS += lib_rintf.c
 endif
diff --git a/libs/libm/libm/lib_llrint.c b/libs/libm/libm/lib_llrint.c
new file mode 100644
index 00000000000..e63f8a949ac
--- /dev/null
+++ b/libs/libm/libm/lib_llrint.c
@@ -0,0 +1,41 @@
+/****************************************************************************
+ * libs/libm/libm/lib_llrint.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/compiler.h>
+
+#include <math.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+#ifdef CONFIG_HAVE_DOUBLE
+long long llrint(double x)
+{
+  return (long long)nearbyint(x);
+}
+#endif
diff --git a/libs/libm/libm/lib_llrintf.c b/libs/libm/libm/lib_llrintf.c
new file mode 100644
index 00000000000..0c013ad6aad
--- /dev/null
+++ b/libs/libm/libm/lib_llrintf.c
@@ -0,0 +1,36 @@
+/****************************************************************************
+ * libs/libm/libm/lib_llrintf.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <math.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+long long llrintf(float x)
+{
+  return (long long)nearbyintf(x);
+}
diff --git a/libs/libm/libm/lib_llrintl.c b/libs/libm/libm/lib_llrintl.c
new file mode 100644
index 00000000000..f3a7993e74f
--- /dev/null
+++ b/libs/libm/libm/lib_llrintl.c
@@ -0,0 +1,41 @@
+/****************************************************************************
+ * libs/libm/libm/lib_llrintl.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/compiler.h>
+
+#include <math.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+#ifdef CONFIG_HAVE_LONG_DOUBLE
+long long llrintl(long double x)
+{
+  return (long long)nearbyintl(x);
+}
+#endif
diff --git a/libs/libm/libm/lib_lrint.c b/libs/libm/libm/lib_lrint.c
new file mode 100644
index 00000000000..93f16cf364a
--- /dev/null
+++ b/libs/libm/libm/lib_lrint.c
@@ -0,0 +1,41 @@
+/****************************************************************************
+ * libs/libm/libm/lib_lrint.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/compiler.h>
+
+#include <math.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+#ifdef CONFIG_HAVE_DOUBLE
+long lrint(double x)
+{
+  return (long)nearbyint(x);
+}
+#endif
diff --git a/libs/libm/libm/lib_lrintf.c b/libs/libm/libm/lib_lrintf.c
new file mode 100644
index 00000000000..28848f7f9c1
--- /dev/null
+++ b/libs/libm/libm/lib_lrintf.c
@@ -0,0 +1,36 @@
+/****************************************************************************
+ * libs/libm/libm/lib_lrintf.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <math.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+long lrintf(float x)
+{
+  return (long)nearbyintf(x);
+}
diff --git a/libs/libm/libm/lib_lrintl.c b/libs/libm/libm/lib_lrintl.c
new file mode 100644
index 00000000000..bc9f7f9c6bd
--- /dev/null
+++ b/libs/libm/libm/lib_lrintl.c
@@ -0,0 +1,41 @@
+/****************************************************************************
+ * libs/libm/libm/lib_lrintl.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/compiler.h>
+
+#include <math.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+#ifdef CONFIG_HAVE_LONG_DOUBLE
+long lrintl(long double x)
+{
+  return (long)nearbyintl(x);
+}
+#endif
diff --git a/libs/libm/libm/lib_nearbyint.c b/libs/libm/libm/lib_nearbyint.c
new file mode 100644
index 00000000000..a66e6f1f58c
--- /dev/null
+++ b/libs/libm/libm/lib_nearbyint.c
@@ -0,0 +1,65 @@
+/****************************************************************************
+ * libs/libm/libm/lib_nearbyint.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/compiler.h>
+
+#include <float.h>
+#include <math.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+#ifdef CONFIG_HAVE_DOUBLE
+double nearbyint(double x)
+{
+  /* Adding and subtracting 1 / EPSILON rounds a smaller |x| to an integer
+   * in the current rounding mode.  A larger |x| is an integer already.
+   */
+
+  const double toint = 1.0 / DBL_EPSILON;
+  volatile double y;
+
+  if (!(fabs(x) < toint))
+    {
+      return x;
+    }
+
+  if (x < 0.0)
+    {
+      y = x - toint;
+      y = y + toint;
+    }
+  else
+    {
+      y = x + toint;
+      y = y - toint;
+    }
+
+  return copysign(y, x);
+}
+#endif
diff --git a/libs/libm/libm/lib_nearbyintf.c b/libs/libm/libm/lib_nearbyintf.c
new file mode 100644
index 00000000000..9361ac0611c
--- /dev/null
+++ b/libs/libm/libm/lib_nearbyintf.c
@@ -0,0 +1,60 @@
+/****************************************************************************
+ * libs/libm/libm/lib_nearbyintf.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <float.h>
+#include <math.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+float nearbyintf(float x)
+{
+  /* Adding and subtracting 1 / EPSILON rounds a smaller |x| to an integer
+   * in the current rounding mode.  A larger |x| is an integer already.
+   */
+
+  const float toint = 1.0F / FLT_EPSILON;
+  volatile float y;
+
+  if (!(fabsf(x) < toint))
+    {
+      return x;
+    }
+
+  if (x < 0.0F)
+    {
+      y = x - toint;
+      y = y + toint;
+    }
+  else
+    {
+      y = x + toint;
+      y = y - toint;
+    }
+
+  return copysignf(y, x);
+}
diff --git a/libs/libm/libm/lib_nearbyintl.c b/libs/libm/libm/lib_nearbyintl.c
new file mode 100644
index 00000000000..15e5da634d4
--- /dev/null
+++ b/libs/libm/libm/lib_nearbyintl.c
@@ -0,0 +1,65 @@
+/****************************************************************************
+ * libs/libm/libm/lib_nearbyintl.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/compiler.h>
+
+#include <float.h>
+#include <math.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+#ifdef CONFIG_HAVE_LONG_DOUBLE
+long double nearbyintl(long double x)
+{
+  /* Adding and subtracting 1 / EPSILON rounds a smaller |x| to an integer
+   * in the current rounding mode.  A larger |x| is an integer already.
+   */
+
+  const long double toint = 1.0L / LDBL_EPSILON;
+  volatile long double y;
+
+  if (!(fabsl(x) < toint))
+    {
+      return x;
+    }
+
+  if (x < 0.0L)
+    {
+      y = x - toint;
+      y = y + toint;
+    }
+  else
+    {
+      y = x + toint;
+      y = y - toint;
+    }
+
+  return copysignl(y, x);
+}
+#endif

Reply via email to