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

   ## Summary
   
   `frexp()` computes the exponent as `ceil(log2(x))` and divides by 
`ldexp(1.0, exponent)`:
   
   - for a power of two, it returns a mantissa of 1, not 0.5;
   - for a negative number, zero or a subnormal, `log2()` gives NaN or -inf, 
and the conversion to int gives a wrong exponent;
   - `ldexp()` is `x * pow(2.0, n)`, which is not exact, and overflows when 2^n 
is out of range but the result is not.
   
   Code that checks the `frexp()` result fails. For example, the gnulib 
`printf` replacement calls `abort()` when the mantissa is not in [0.5, 1).
   
   This PR takes the exponent from the IEEE bits in `frexp()` and `frexpf()`, 
scales by powers of two in `frexpl()`, and uses `scalbn()` in `ldexp()`, 
`ldexpf()` and `ldexpl()`.
   
   ## Impact
   
   `frexp()`, `frexpf()`, `frexpl()`, `ldexp()`, `ldexpf()` and `ldexpl()` of 
the NuttX libm (`CONFIG_LIBM`). The results are now exact. No API change.
   
   ## Testing
   
   Host test: the NuttX `lib_frexp*.c`, `lib_ldexp*.c` and `lib_scalbn*.c` 
compiled on arm64 Linux (Docker, 128-bit long double) and compared bit for bit 
with glibc on 2 million random values, the special values (0, -0, inf, NaN) and 
subnormals, for float, double and long double.
   
   ```
   master:  frexp(0x0p+0): nx nan -2147483648 libc 0x0p+0 0
            ldexpf(0x0p+0,158): nx nan libc 0x0p+0
            FAILED (1260341 bad)
   this PR: PASSED (0 bad)
   ```
   
   Build: `qemu-armv8a:nsh`, `qemu-armv8a:knsh` and `lm3s6965-ek:qemu-flat`.
   


-- 
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