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
