casaroli opened a new pull request, #20841:
URL: https://github.com/apache/nuttx/pull/20841

   ## Summary
   
   `include/nuttx/lib/math.h` declares the C99 math functions, but the built-in 
libm (`CONFIG_LIBM`) did not define 50 of them. A program that calls one of 
them did not link with the built-in libm; C++ `std::hypot`, for example, needs 
`hypot()`. This PR adds them, in one commit for each group of functions:
   
   - `nearbyint()`, `lrint()`, `llrint()` (the generic `nearbyint()` and 
`nearbyintf()` are not built when `CONFIG_LIBM_ARCH_NEARBYINT(F)` selects the 
ARMv8-M versions)
   - `fdim()`, `ilogb()`, `logb()`, `scalbln()`, `nextafter()`, `nexttoward()`, 
`remainder()`, `remquo()` (and `FP_ILOGB0`, `FP_ILOGBNAN` in `math.h`)
   - `fma()`, `fmal()`
   - `exp2()`, `log1p()`, `hypot()`, `cbrtf()`, `cbrtl()`
   - `lgammaf()`, `lgammal()`, `tgammaf()`, `tgammal()`
   
   Each group has the `float`, `double` and `long double` versions. The 
functions that must be exact are exact: `remquo()` does a long division with 
exact steps, `fma()` adds the exact product (Dekker) to z with one rounding 
(rounding to odd, Boldo and Melquiond), or uses the instruction when the 
compiler has one (`__FP_FAST_FMA`). The `long double` versions do not depend on 
the format, so they work for binary64, x87 and binary128.
   
   Three commits before them fix bugs in existing functions that the new 
functions use or that the tests found:
   
   - `fabs(-0.0)` returned `-0.0` (and so `copysign(-0.0, 1.0)` too).
   - `logl()` did not return for some arguments, for example 
`0x1.61192641b328cp+0` when `long double` is `double`. It now relaxes its limit 
like `log()` and `logf()`.
   - `cbrt()` returned 0 for `|x| < DBL_EPSILON` and `cbrt(27.0)` was 
`2.9999999999999996`.
   
   ## Impact
   
   New functions in the built-in libm only; the linker takes only the functions 
that a program uses. `LIBM_NEWLIB`, `LIBM_OPENLIBM`, `LIBM_LIBMCS` and 
`LIBM_TOOLCHAIN` do not change. Only the rounding to nearest is supported, as 
in the rest of the built-in libm. The accuracy of `exp2()` and `log1p()` 
follows that of `exp()` and `log()`: within 6 ulp in the tests for `float` and 
`double`; the `long double` versions have the precision of `expl()` and 
`logl()`, which is about that of `double`. `lgammal()` and `tgammal()` call the 
`double` versions, as `expl()` and `logl()` also have the range of `double`.
   
   ## Testing
   
   - A test program on `qemu-armv8a:knsh` (binary128 `long double`, QEMU 11 
with HVF on an Apple M4): 368 checks of the `float`, `double` and `long double` 
versions against a table made with the host libm, and exact binary128 checks 
(`fmal()`, `nextafterl()`, `nearbyintl()`, `ilogbl()`, `remquol(0x1p16000L, 
3)`, `exp2l(16000)`). On master the program does not link (49 undefined 
references); with this PR it passes.
   - 400 random `fmal()`, `remquol()` and `nextafterl()` results each on 
`qemu-armv8a:knsh`, checked exactly with rational arithmetic on the host: no 
difference.
   - The libm compiled for the host (macOS, arm64 and x86_64 with an 80-bit 
`long double`) against the host libm, 200000 random and special arguments for 
each function: the exact functions (`nearbyint`, `lrint`, `llrint`, `fdim`, 
`ilogb`, `logb`, `scalbln`, `nextafter`, `nexttoward`, `remainder`, `remquo`, 
`fma`) give the same bits for all three types (on x86_64 the host `remquol()` 
and `fmal()` are wrong for some arguments, so 3000 results of each were checked 
with rational arithmetic instead: no difference); `cbrt` is within 1 ulp, 
`hypot` within 2 ulp, `exp2` and `log1p` within 6 ulp (`log1p(x)` for x > 1e304 
returns infinity because `log()` does).
   - `ostest` on `qemu-armv8a:knsh` and `qemu-armv8a:nsh` ends with 
`ostest_main: Exiting with status 0`.
   - Builds with no new warnings (gcc 15.3): `qemu-armv7a:nsh`; 
`qemu-armv7a:knsh` with `CONFIG_LIBM`; `mps3-an547:nsh` with `CONFIG_LIBM` and 
`CONFIG_ARMV8M_LIBM` (the ARMv8-M `nearbyintf()` replaces the generic one). 
`sim:nsh` with `CONFIG_LIBM` compiles the new files with no warnings (on macOS 
it does not link because of `TIOCGPTN` in `sim_hostuart.c`, the same on master).
   - `tools/checkpatch.sh -c -u -m -g` passes.
   
   Documentation: no change; `Documentation/standards/posix.rst` lists the math 
functions without a support column, and says that the set depends on the libm 
choice.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to