On Tue, 7 Sep 2021, Patrick Northon wrote:
Take number 2. I moved the adjustment to the exponent into __pformat_xldouble.
Thanks for this attempt. Now I've poked the implementation to follow it a bit better to see what happens, and now I see the point in your original form of the patch - but I think it can be achieved with a bit less adjustments back and forth. What do you think about the attached patch?
// Martin
From bc9d83f66c2147f7695efb543502216a12a4d548 Mon Sep 17 00:00:00 2001 From: Patrick Northon <[email protected]> Date: Sun, 5 Sep 2021 17:31:17 -0400 Subject: [PATCH] Fix exponent when formatting long double in hexadecimal. Some denormalized values were emited incorrectly. The leading digit will always assume to start at the 4th bit from the highest order bit in the mantissa and the exponent will be adjusted accordingly. --- mingw-w64-crt/stdio/mingw_pformat.c | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/mingw-w64-crt/stdio/mingw_pformat.c b/mingw-w64-crt/stdio/mingw_pformat.c index b2e1af6ec..3f1513516 100644 --- a/mingw-w64-crt/stdio/mingw_pformat.c +++ b/mingw-w64-crt/stdio/mingw_pformat.c @@ -2002,6 +2002,17 @@ void __pformat_emit_xfloat( __pformat_fpreg_t value, __pformat_t *stream ) char buf[18 + 6], *p = buf; __pformat_intarg_t exponent; short exp_width = 2; + if (value.__pformat_fpreg_mantissa != 0 || + value.__pformat_fpreg_exponent != 0) + { + /* Reduce the exponent since the leading digit emited will start at + * the 4th bit from the highest order bit instead, the later being + * the leading digit of the floating point. Don't do this adjustment + * if the value is an actual zero. + */ + value.__pformat_fpreg_exponent -= 3; + } + /* The mantissa field of the argument value representation can * accommodate at most 16 hexadecimal digits, of which one will * be placed before the radix point, leaving at most 15 digits @@ -2045,7 +2056,7 @@ void __pformat_emit_xfloat( __pformat_fpreg_t value, __pformat_t *stream ) * of this is equivalent to an increment of the exponent. We will * discard a whole digit to match glibc's behavior. */ - value.__pformat_fpreg_exponent++; + value.__pformat_fpreg_exponent += 4; value.__pformat_fpreg_mantissa >>= 3; } @@ -2086,20 +2097,6 @@ void __pformat_emit_xfloat( __pformat_fpreg_t value, __pformat_t *stream ) */ *p++ = '.'; } - - /* If the most significant hexadecimal digit of the encoded - * output value is greater than one, then the indicated value - * will appear too large, by an additional binary exponent - * corresponding to the number of higher order bit positions - * which it occupies... - */ - while( value.__pformat_fpreg_mantissa > 1 ) - { - /* so reduce the exponent value to compensate... - */ - value.__pformat_fpreg_exponent--; - value.__pformat_fpreg_mantissa >>= 1; - } } else if( stream->precision > 0 ) @@ -2305,7 +2302,7 @@ void __pformat_xldouble( long double x, __pformat_t *stream ) { /* ...this mantissa represents a subnormal value. */ - z.__pformat_fpreg_exponent = -0x3FFF - 2; + z.__pformat_fpreg_exponent = 1 - 0x3FFF; } } else -- 2.25.1
_______________________________________________ Mingw-w64-public mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
