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 556b9564b28b9a50b64c7c0cac3b321058a9526d Author: Marco Casaroli <[email protected]> AuthorDate: Mon Oct 19 02:30:26 2026 +0200 libs/libm: Add fdim(), ilogb(), logb(), scalbln(), nextafter() and remquo(). math.h declares these functions and their float and long double versions, but the built-in libm did not have them. Add them: - fdim() returns x - y if x > y, else 0. - ilogb() and logb() get the exponent from frexp(). math.h now also defines FP_ILOGB0 and FP_ILOGBNAN, the results of ilogb() for 0 and NaN. - scalbln() limits n to the range of int and calls scalbn(). - nextafter() and nextafterf() change the bit pattern by one. nextafterl() adds or subtracts the distance to the next number, which it gets from frexpl(), so it works for each format of long double. - remquo() does a long division with ay * 2^e for each e down to 0. Each subtraction is exact, so the remainder is exact. remquo() keeps the low 31 bits of the quotient. remainder() calls remquo(). The prototypes of remquo() now have FAR on the quo pointer. Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Marco Casaroli <[email protected]> --- include/nuttx/lib/math.h | 11 +++-- libs/libm/libm/CMakeLists.txt | 24 ++++++++++ libs/libm/libm/Make.defs | 8 ++++ libs/libm/libm/lib_fdim.c | 46 +++++++++++++++++++ libs/libm/libm/lib_fdimf.c | 41 +++++++++++++++++ libs/libm/libm/lib_fdiml.c | 46 +++++++++++++++++++ libs/libm/libm/lib_ilogb.c | 60 +++++++++++++++++++++++++ libs/libm/libm/lib_ilogbf.c | 55 +++++++++++++++++++++++ libs/libm/libm/lib_ilogbl.c | 60 +++++++++++++++++++++++++ libs/libm/libm/lib_logb.c | 51 +++++++++++++++++++++ libs/libm/libm/lib_logbf.c | 46 +++++++++++++++++++ libs/libm/libm/lib_logbl.c | 51 +++++++++++++++++++++ libs/libm/libm/lib_nextafter.c | 78 ++++++++++++++++++++++++++++++++ libs/libm/libm/lib_nextafterf.c | 73 ++++++++++++++++++++++++++++++ libs/libm/libm/lib_nextafterl.c | 90 +++++++++++++++++++++++++++++++++++++ libs/libm/libm/lib_nexttoward.c | 51 +++++++++++++++++++++ libs/libm/libm/lib_nexttowardf.c | 46 +++++++++++++++++++ libs/libm/libm/lib_nexttowardl.c | 41 +++++++++++++++++ libs/libm/libm/lib_remainder.c | 43 ++++++++++++++++++ libs/libm/libm/lib_remainderf.c | 38 ++++++++++++++++ libs/libm/libm/lib_remainderl.c | 43 ++++++++++++++++++ libs/libm/libm/lib_remquo.c | 97 ++++++++++++++++++++++++++++++++++++++++ libs/libm/libm/lib_remquof.c | 92 +++++++++++++++++++++++++++++++++++++ libs/libm/libm/lib_remquol.c | 97 ++++++++++++++++++++++++++++++++++++++++ libs/libm/libm/lib_scalbln.c | 53 ++++++++++++++++++++++ libs/libm/libm/lib_scalblnf.c | 48 ++++++++++++++++++++ libs/libm/libm/lib_scalblnl.c | 53 ++++++++++++++++++++++ 27 files changed, 1439 insertions(+), 3 deletions(-) diff --git a/include/nuttx/lib/math.h b/include/nuttx/lib/math.h index 771901f7e31..027741e3505 100644 --- a/include/nuttx/lib/math.h +++ b/include/nuttx/lib/math.h @@ -579,12 +579,12 @@ double remainder(double x, double y); long double remainderl(long double x, long double y); #endif -float remquof(float x, float y, int *quo); +float remquof(float x, float y, FAR int *quo); #ifdef CONFIG_HAVE_DOUBLE -double remquo(double x, double y, int *quo); +double remquo(double x, double y, FAR int *quo); #endif #ifdef CONFIG_HAVE_LONG_DOUBLE -long double remquol(long double x, long double y, int *quo); +long double remquol(long double x, long double y, FAR int *quo); #endif float scalblnf(float x, long int n); @@ -603,6 +603,11 @@ double scalbn(double x, int n); long double scalbnl(long double x, int n); #endif +/* Values of ilogb() for zero and NaN */ + +#define FP_ILOGBNAN ((int)(~0u >> 1)) +#define FP_ILOGB0 (-FP_ILOGBNAN) + #define FP_INFINITE 0 #define FP_NAN 1 #define FP_NORMAL 2 diff --git a/libs/libm/libm/CMakeLists.txt b/libs/libm/libm/CMakeLists.txt index b1da10ee3f5..650710a7dff 100644 --- a/libs/libm/libm/CMakeLists.txt +++ b/libs/libm/libm/CMakeLists.txt @@ -151,6 +151,30 @@ if(CONFIG_LIBM) __sin.c lib_gamma.c lib_lgamma.c + lib_fdim.c + lib_fdimf.c + lib_fdiml.c + lib_ilogb.c + lib_ilogbf.c + lib_ilogbl.c + lib_logb.c + lib_logbf.c + lib_logbl.c + lib_scalbln.c + lib_scalblnf.c + lib_scalblnl.c + lib_nextafter.c + lib_nextafterf.c + lib_nextafterl.c + lib_nexttoward.c + lib_nexttowardf.c + lib_nexttowardl.c + lib_remainder.c + lib_remainderf.c + lib_remainderl.c + lib_remquo.c + lib_remquof.c + lib_remquol.c lib_lrint.c lib_lrintf.c lib_lrintl.c diff --git a/libs/libm/libm/Make.defs b/libs/libm/libm/Make.defs index 0196b8dc32b..3b97c64d24e 100644 --- a/libs/libm/libm/Make.defs +++ b/libs/libm/libm/Make.defs @@ -57,6 +57,14 @@ 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_fdim.c lib_fdimf.c lib_fdiml.c +CSRCS += lib_ilogb.c lib_ilogbf.c lib_ilogbl.c +CSRCS += lib_logb.c lib_logbf.c lib_logbl.c +CSRCS += lib_scalbln.c lib_scalblnf.c lib_scalblnl.c +CSRCS += lib_nextafter.c lib_nextafterf.c lib_nextafterl.c +CSRCS += lib_nexttoward.c lib_nexttowardf.c lib_nexttowardl.c +CSRCS += lib_remainder.c lib_remainderf.c lib_remainderl.c +CSRCS += lib_remquo.c lib_remquof.c lib_remquol.c CSRCS += lib_lrint.c lib_lrintf.c lib_lrintl.c CSRCS += lib_llrint.c lib_llrintf.c lib_llrintl.c lib_nearbyintl.c diff --git a/libs/libm/libm/lib_fdim.c b/libs/libm/libm/lib_fdim.c new file mode 100644 index 00000000000..34d54a76a02 --- /dev/null +++ b/libs/libm/libm/lib_fdim.c @@ -0,0 +1,46 @@ +/**************************************************************************** + * libs/libm/libm/lib_fdim.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 +double fdim(double x, double y) +{ + if (isnan(x) || isnan(y)) + { + return x + y; + } + + return x > y ? x - y : 0.0; +} +#endif diff --git a/libs/libm/libm/lib_fdimf.c b/libs/libm/libm/lib_fdimf.c new file mode 100644 index 00000000000..612bfcd9d1c --- /dev/null +++ b/libs/libm/libm/lib_fdimf.c @@ -0,0 +1,41 @@ +/**************************************************************************** + * libs/libm/libm/lib_fdimf.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 + ****************************************************************************/ + +float fdimf(float x, float y) +{ + if (isnan(x) || isnan(y)) + { + return x + y; + } + + return x > y ? x - y : 0.0F; +} diff --git a/libs/libm/libm/lib_fdiml.c b/libs/libm/libm/lib_fdiml.c new file mode 100644 index 00000000000..af6a66b5c73 --- /dev/null +++ b/libs/libm/libm/lib_fdiml.c @@ -0,0 +1,46 @@ +/**************************************************************************** + * libs/libm/libm/lib_fdiml.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 double fdiml(long double x, long double y) +{ + if (isnan(x) || isnan(y)) + { + return x + y; + } + + return x > y ? x - y : 0.0L; +} +#endif diff --git a/libs/libm/libm/lib_ilogb.c b/libs/libm/libm/lib_ilogb.c new file mode 100644 index 00000000000..800bb2155ac --- /dev/null +++ b/libs/libm/libm/lib_ilogb.c @@ -0,0 +1,60 @@ +/**************************************************************************** + * libs/libm/libm/lib_ilogb.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 <limits.h> +#include <math.h> + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef CONFIG_HAVE_DOUBLE +int ilogb(double x) +{ + int e; + + if (x == 0.0) + { + return FP_ILOGB0; + } + + if (isnan(x)) + { + return FP_ILOGBNAN; + } + + if (isinf(x)) + { + return INT_MAX; + } + + frexp(x, &e); + return e - 1; +} +#endif diff --git a/libs/libm/libm/lib_ilogbf.c b/libs/libm/libm/lib_ilogbf.c new file mode 100644 index 00000000000..9614fa8cfba --- /dev/null +++ b/libs/libm/libm/lib_ilogbf.c @@ -0,0 +1,55 @@ +/**************************************************************************** + * libs/libm/libm/lib_ilogbf.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 <limits.h> +#include <math.h> + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int ilogbf(float x) +{ + int e; + + if (x == 0.0F) + { + return FP_ILOGB0; + } + + if (isnan(x)) + { + return FP_ILOGBNAN; + } + + if (isinf(x)) + { + return INT_MAX; + } + + frexpf(x, &e); + return e - 1; +} diff --git a/libs/libm/libm/lib_ilogbl.c b/libs/libm/libm/lib_ilogbl.c new file mode 100644 index 00000000000..1f3f6ff50e0 --- /dev/null +++ b/libs/libm/libm/lib_ilogbl.c @@ -0,0 +1,60 @@ +/**************************************************************************** + * libs/libm/libm/lib_ilogbl.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 <limits.h> +#include <math.h> + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef CONFIG_HAVE_LONG_DOUBLE +int ilogbl(long double x) +{ + int e; + + if (x == 0.0L) + { + return FP_ILOGB0; + } + + if (isnan(x)) + { + return FP_ILOGBNAN; + } + + if (isinf(x)) + { + return INT_MAX; + } + + frexpl(x, &e); + return e - 1; +} +#endif diff --git a/libs/libm/libm/lib_logb.c b/libs/libm/libm/lib_logb.c new file mode 100644 index 00000000000..3c08f14d687 --- /dev/null +++ b/libs/libm/libm/lib_logb.c @@ -0,0 +1,51 @@ +/**************************************************************************** + * libs/libm/libm/lib_logb.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 +double logb(double x) +{ + if (x == 0.0) + { + return -1.0 / fabs(x); + } + + if (isnan(x) || isinf(x)) + { + return x * x; + } + + return (double)ilogb(x); +} +#endif diff --git a/libs/libm/libm/lib_logbf.c b/libs/libm/libm/lib_logbf.c new file mode 100644 index 00000000000..fbdc49c818d --- /dev/null +++ b/libs/libm/libm/lib_logbf.c @@ -0,0 +1,46 @@ +/**************************************************************************** + * libs/libm/libm/lib_logbf.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 + ****************************************************************************/ + +float logbf(float x) +{ + if (x == 0.0F) + { + return -1.0F / fabsf(x); + } + + if (isnan(x) || isinf(x)) + { + return x * x; + } + + return (float)ilogbf(x); +} diff --git a/libs/libm/libm/lib_logbl.c b/libs/libm/libm/lib_logbl.c new file mode 100644 index 00000000000..076f5a5db38 --- /dev/null +++ b/libs/libm/libm/lib_logbl.c @@ -0,0 +1,51 @@ +/**************************************************************************** + * libs/libm/libm/lib_logbl.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 double logbl(long double x) +{ + if (x == 0.0L) + { + return -1.0L / fabsl(x); + } + + if (isnan(x) || isinf(x)) + { + return x * x; + } + + return (long double)ilogbl(x); +} +#endif diff --git a/libs/libm/libm/lib_nextafter.c b/libs/libm/libm/lib_nextafter.c new file mode 100644 index 00000000000..217ca9d8a88 --- /dev/null +++ b/libs/libm/libm/lib_nextafter.c @@ -0,0 +1,78 @@ +/**************************************************************************** + * libs/libm/libm/lib_nextafter.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> +#include <stdint.h> + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef CONFIG_HAVE_DOUBLE +double nextafter(double x, double y) +{ + union + { + double f; + uint64_t i; + } u; + + if (isnan(x) || isnan(y)) + { + return x + y; + } + + if (x == y) + { + return y; + } + + if (x == 0.0) + { + /* The smallest subnormal number, with the sign of y */ + + u.i = 1; + return y > 0.0 ? u.f : -u.f; + } + + /* The next number has the next bit pattern in the direction of y */ + + u.f = x; + if ((x < y) == (x > 0.0)) + { + u.i++; + } + else + { + u.i--; + } + + return u.f; +} +#endif diff --git a/libs/libm/libm/lib_nextafterf.c b/libs/libm/libm/lib_nextafterf.c new file mode 100644 index 00000000000..956ad3db93c --- /dev/null +++ b/libs/libm/libm/lib_nextafterf.c @@ -0,0 +1,73 @@ +/**************************************************************************** + * libs/libm/libm/lib_nextafterf.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> +#include <stdint.h> + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +float nextafterf(float x, float y) +{ + union + { + float f; + uint32_t i; + } u; + + if (isnan(x) || isnan(y)) + { + return x + y; + } + + if (x == y) + { + return y; + } + + if (x == 0.0F) + { + /* The smallest subnormal number, with the sign of y */ + + u.i = 1; + return y > 0.0F ? u.f : -u.f; + } + + /* The next number has the next bit pattern in the direction of y */ + + u.f = x; + if ((x < y) == (x > 0.0F)) + { + u.i++; + } + else + { + u.i--; + } + + return u.f; +} diff --git a/libs/libm/libm/lib_nextafterl.c b/libs/libm/libm/lib_nextafterl.c new file mode 100644 index 00000000000..92b166dee5b --- /dev/null +++ b/libs/libm/libm/lib_nextafterl.c @@ -0,0 +1,90 @@ +/**************************************************************************** + * libs/libm/libm/lib_nextafterl.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 +#if LDBL_MANT_DIG == DBL_MANT_DIG +long double nextafterl(long double x, long double y) +{ + return nextafter(x, y); +} +#else +long double nextafterl(long double x, long double y) +{ + long double ulp; + int e; + + if (isnan(x) || isnan(y)) + { + return x + y; + } + + if (x == y) + { + return y; + } + + if (x == 0.0L) + { + ulp = scalbnl(1.0L, LDBL_MIN_EXP - LDBL_MANT_DIG); + return y > 0.0L ? ulp : -ulp; + } + + if (isinf(x)) + { + return x > 0.0L ? LDBL_MAX : -LDBL_MAX; + } + + /* x = m * 2^e with |m| in [0.5, 1): the distance to the next number is + * 2^(e - LDBL_MANT_DIG), half of it below a power of two, and not less + * than the distance between subnormal numbers. + */ + + if (fabsl(frexpl(x, &e)) == 0.5L && (y > x) != (x > 0.0L) && + e > LDBL_MIN_EXP) + { + e--; + } + + if (e < LDBL_MIN_EXP) + { + e = LDBL_MIN_EXP; + } + + ulp = scalbnl(1.0L, e - LDBL_MANT_DIG); + return y > x ? x + ulp : x - ulp; +} +#endif +#endif diff --git a/libs/libm/libm/lib_nexttoward.c b/libs/libm/libm/lib_nexttoward.c new file mode 100644 index 00000000000..0411004ba90 --- /dev/null +++ b/libs/libm/libm/lib_nexttoward.c @@ -0,0 +1,51 @@ +/**************************************************************************** + * libs/libm/libm/lib_nexttoward.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 +double nexttoward(double x, long double y) +{ + if (isnan(x) || isnan(y)) + { + return x + y; + } + + if ((long double)x == y) + { + return y; + } + + return nextafter(x, (long double)x < y ? INFINITY : -INFINITY); +} +#endif diff --git a/libs/libm/libm/lib_nexttowardf.c b/libs/libm/libm/lib_nexttowardf.c new file mode 100644 index 00000000000..ed86ba281ff --- /dev/null +++ b/libs/libm/libm/lib_nexttowardf.c @@ -0,0 +1,46 @@ +/**************************************************************************** + * libs/libm/libm/lib_nexttowardf.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 + ****************************************************************************/ + +float nexttowardf(float x, long double y) +{ + if (isnan(x) || isnan(y)) + { + return x + y; + } + + if ((long double)x == y) + { + return y; + } + + return nextafterf(x, (long double)x < y ? INFINITY_F : -INFINITY_F); +} diff --git a/libs/libm/libm/lib_nexttowardl.c b/libs/libm/libm/lib_nexttowardl.c new file mode 100644 index 00000000000..254136dd62d --- /dev/null +++ b/libs/libm/libm/lib_nexttowardl.c @@ -0,0 +1,41 @@ +/**************************************************************************** + * libs/libm/libm/lib_nexttowardl.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 double nexttowardl(long double x, long double y) +{ + return nextafterl(x, y); +} +#endif diff --git a/libs/libm/libm/lib_remainder.c b/libs/libm/libm/lib_remainder.c new file mode 100644 index 00000000000..ad31eab8e8b --- /dev/null +++ b/libs/libm/libm/lib_remainder.c @@ -0,0 +1,43 @@ +/**************************************************************************** + * libs/libm/libm/lib_remainder.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 +double remainder(double x, double y) +{ + int quo; + + return remquo(x, y, &quo); +} +#endif diff --git a/libs/libm/libm/lib_remainderf.c b/libs/libm/libm/lib_remainderf.c new file mode 100644 index 00000000000..c944a6070da --- /dev/null +++ b/libs/libm/libm/lib_remainderf.c @@ -0,0 +1,38 @@ +/**************************************************************************** + * libs/libm/libm/lib_remainderf.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 + ****************************************************************************/ + +float remainderf(float x, float y) +{ + int quo; + + return remquof(x, y, &quo); +} diff --git a/libs/libm/libm/lib_remainderl.c b/libs/libm/libm/lib_remainderl.c new file mode 100644 index 00000000000..123f76f0b5e --- /dev/null +++ b/libs/libm/libm/lib_remainderl.c @@ -0,0 +1,43 @@ +/**************************************************************************** + * libs/libm/libm/lib_remainderl.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 double remainderl(long double x, long double y) +{ + int quo; + + return remquol(x, y, &quo); +} +#endif diff --git a/libs/libm/libm/lib_remquo.c b/libs/libm/libm/lib_remquo.c new file mode 100644 index 00000000000..c035573b506 --- /dev/null +++ b/libs/libm/libm/lib_remquo.c @@ -0,0 +1,97 @@ +/**************************************************************************** + * libs/libm/libm/lib_remquo.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> +#include <stdint.h> + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef CONFIG_HAVE_DOUBLE +double remquo(double x, double y, FAR int *quo) +{ + double ax = fabs(x); + double ay = fabs(y); + double t; + uint32_t q = 0; + int e; + + *quo = 0; + if (isnan(x) || isnan(y) || isinf(x) || y == 0.0) + { + return (x * y) / (x * y); + } + + if (x == 0.0 || isinf(y)) + { + return x; + } + + /* Long division: subtract ay * 2^e from ax for e down to 0. Each step + * is exact, so the remainder is exact. Keep the low quotient bits. + */ + + e = ilogb(ax) - ilogb(ay); + if (e >= 0) + { + t = scalbn(ay, e); + for (; ; ) + { + if (ax >= t) + { + ax -= t; + if (e < 31) + { + q |= (uint32_t)1 << e; + } + } + + if (e-- == 0) + { + break; + } + + t *= 0.5; + } + } + + /* Round the quotient to the nearest integer, ties to even */ + + if (ax + ax > ay || (ax + ax == ay && (q & 1) != 0)) + { + ax -= ay; + q++; + } + + q &= 0x7fffffff; + *quo = (x < 0.0) != (y < 0.0) ? -(int)q : (int)q; + return x < 0.0 ? -ax : ax; +} +#endif diff --git a/libs/libm/libm/lib_remquof.c b/libs/libm/libm/lib_remquof.c new file mode 100644 index 00000000000..77314983193 --- /dev/null +++ b/libs/libm/libm/lib_remquof.c @@ -0,0 +1,92 @@ +/**************************************************************************** + * libs/libm/libm/lib_remquof.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> +#include <stdint.h> + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +float remquof(float x, float y, FAR int *quo) +{ + float ax = fabsf(x); + float ay = fabsf(y); + float t; + uint32_t q = 0; + int e; + + *quo = 0; + if (isnan(x) || isnan(y) || isinf(x) || y == 0.0F) + { + return (x * y) / (x * y); + } + + if (x == 0.0F || isinf(y)) + { + return x; + } + + /* Long division: subtract ay * 2^e from ax for e down to 0. Each step + * is exact, so the remainder is exact. Keep the low quotient bits. + */ + + e = ilogbf(ax) - ilogbf(ay); + if (e >= 0) + { + t = scalbnf(ay, e); + for (; ; ) + { + if (ax >= t) + { + ax -= t; + if (e < 31) + { + q |= (uint32_t)1 << e; + } + } + + if (e-- == 0) + { + break; + } + + t *= 0.5F; + } + } + + /* Round the quotient to the nearest integer, ties to even */ + + if (ax + ax > ay || (ax + ax == ay && (q & 1) != 0)) + { + ax -= ay; + q++; + } + + q &= 0x7fffffff; + *quo = (x < 0.0F) != (y < 0.0F) ? -(int)q : (int)q; + return x < 0.0F ? -ax : ax; +} diff --git a/libs/libm/libm/lib_remquol.c b/libs/libm/libm/lib_remquol.c new file mode 100644 index 00000000000..b1c92db7803 --- /dev/null +++ b/libs/libm/libm/lib_remquol.c @@ -0,0 +1,97 @@ +/**************************************************************************** + * libs/libm/libm/lib_remquol.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> +#include <stdint.h> + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef CONFIG_HAVE_LONG_DOUBLE +long double remquol(long double x, long double y, FAR int *quo) +{ + long double ax = fabsl(x); + long double ay = fabsl(y); + long double t; + uint32_t q = 0; + int e; + + *quo = 0; + if (isnan(x) || isnan(y) || isinf(x) || y == 0.0L) + { + return (x * y) / (x * y); + } + + if (x == 0.0L || isinf(y)) + { + return x; + } + + /* Long division: subtract ay * 2^e from ax for e down to 0. Each step + * is exact, so the remainder is exact. Keep the low quotient bits. + */ + + e = ilogbl(ax) - ilogbl(ay); + if (e >= 0) + { + t = scalbnl(ay, e); + for (; ; ) + { + if (ax >= t) + { + ax -= t; + if (e < 31) + { + q |= (uint32_t)1 << e; + } + } + + if (e-- == 0) + { + break; + } + + t *= 0.5L; + } + } + + /* Round the quotient to the nearest integer, ties to even */ + + if (ax + ax > ay || (ax + ax == ay && (q & 1) != 0)) + { + ax -= ay; + q++; + } + + q &= 0x7fffffff; + *quo = (x < 0.0L) != (y < 0.0L) ? -(int)q : (int)q; + return x < 0.0L ? -ax : ax; +} +#endif diff --git a/libs/libm/libm/lib_scalbln.c b/libs/libm/libm/lib_scalbln.c new file mode 100644 index 00000000000..e67d87f38e3 --- /dev/null +++ b/libs/libm/libm/lib_scalbln.c @@ -0,0 +1,53 @@ +/**************************************************************************** + * libs/libm/libm/lib_scalbln.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 <limits.h> +#include <math.h> + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef CONFIG_HAVE_DOUBLE +double scalbln(double x, long int n) +{ +#if LONG_MAX > INT_MAX + if (n > INT_MAX) + { + n = INT_MAX; + } + else if (n < INT_MIN) + { + n = INT_MIN; + } +#endif + + return scalbn(x, (int)n); +} +#endif diff --git a/libs/libm/libm/lib_scalblnf.c b/libs/libm/libm/lib_scalblnf.c new file mode 100644 index 00000000000..593396e3ead --- /dev/null +++ b/libs/libm/libm/lib_scalblnf.c @@ -0,0 +1,48 @@ +/**************************************************************************** + * libs/libm/libm/lib_scalblnf.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 <limits.h> +#include <math.h> + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +float scalblnf(float x, long int n) +{ +#if LONG_MAX > INT_MAX + if (n > INT_MAX) + { + n = INT_MAX; + } + else if (n < INT_MIN) + { + n = INT_MIN; + } +#endif + + return scalbnf(x, (int)n); +} diff --git a/libs/libm/libm/lib_scalblnl.c b/libs/libm/libm/lib_scalblnl.c new file mode 100644 index 00000000000..cc4bfb8a0db --- /dev/null +++ b/libs/libm/libm/lib_scalblnl.c @@ -0,0 +1,53 @@ +/**************************************************************************** + * libs/libm/libm/lib_scalblnl.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 <limits.h> +#include <math.h> + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef CONFIG_HAVE_LONG_DOUBLE +long double scalblnl(long double x, long int n) +{ +#if LONG_MAX > INT_MAX + if (n > INT_MAX) + { + n = INT_MAX; + } + else if (n < INT_MIN) + { + n = INT_MIN; + } +#endif + + return scalbnl(x, (int)n); +} +#endif
