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 c1e02c88eb9d086ee1d474e0ff8ccae186a7b87e
Author: Marco Casaroli <[email protected]>
AuthorDate: Thu Nov 5 15:46:41 2026 +0100

    libs/libc/stream: Print the sign of a negative zero in printf().
    
    The floating point engine tested the sign with x < 0, and this is false
    for -0.0.  %f, %e and %g of -0.0 printed "0.000000", "0.000000e+00" and
    "0", and %+f printed "+0.000000".  C requires the sign.
    
    Test the sign bit of the value.  A compare needs a call of the soft-float
    code on a CPU with no FPU, and a test of one byte needs no call, so the
    object is smaller there.  A byte works on every compiler and for each
    size of double.
    
    A NaN with its sign bit set now prints "-nan", as the standard allows and
    as C23 requires.
    
    Part of https://github.com/apache/nuttx/issues/21467
    
    Assisted-by: Claude Code:claude-opus-5-5
    Signed-off-by: Marco Casaroli <[email protected]>
---
 libs/libc/stream/lib_dtoa_engine.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/libs/libc/stream/lib_dtoa_engine.c 
b/libs/libc/stream/lib_dtoa_engine.c
index d7155305c9b..75c5e339aa4 100644
--- a/libs/libc/stream/lib_dtoa_engine.c
+++ b/libs/libc/stream/lib_dtoa_engine.c
@@ -72,6 +72,12 @@
 #define MIN_MANT_INT  ((uint64_t)MIN_MANT)
 #define MIN_MANT_EXP  DBL_DIG
 
+#ifdef CONFIG_ENDIAN_BIG
+#  define DTOA_SIGN_BYTE 0
+#else
+#  define DTOA_SIGN_BYTE (sizeof(double) - 1)
+#endif
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -79,11 +85,20 @@
 int __dtoa_engine(double x, FAR struct dtoa_s *dtoa, int max_digits,
                   int max_decimals)
 {
+  union
+  {
+    double d;
+    uint8_t b[sizeof(double)];
+  } sign;
+
   int32_t exp = 0;
   uint8_t flags = 0;
   int i;
 
-  if (x < 0)
+  /* The sign bit, because -0.0 < 0 is false */
+
+  sign.d = x;
+  if ((sign.b[DTOA_SIGN_BYTE] & 0x80) != 0)
     {
       flags |= DTOA_MINUS;
       x = -x;

Reply via email to