The attached patch with assistance implements the various rounding modes for the
WRITE with EX hexadecimal float output.
This continues the effort to get the full EX support completed. A followup patch
will take care of the READ EX portion.
This has been regression tested on x86_64.
OK for mainline?
Regards,
Jerry
-----
Fortran: [PR93727] Add EX format rounding for truncated hex mantissa
Implement proper rounding of the hex mantissa in write_ex when the
user specifies a d smaller than full precision. All Fortran ROUND=
modes are supported: ROUND_NEAREST (ties-to-even), ROUND_COMPATIBLE
(ties away from zero), ROUND_UP, ROUND_DOWN, and ROUND_ZERO.
ROUND_PROCDEFINED and ROUND_UNSPECIFIED default to ROUND_NEAREST on
IEEE 754 systems, consistent with the decimal format behaviour.
Carry propagation handles the case where incrementing a string of
trailing F hex digits reaches the integer digit; if that overflows
(F → 16) the output is normalized by setting the integer digit to 8
and incrementing the binary exponent by one.
Assisted by: Claude Sonnet 4.6
PR fortran/93727
libgfortran/ChangeLog:
* io/write.c (write_ex): Replace simple truncation with
rounding-aware logic respecting dtp round_status. Add carry
propagation and integer-digit normalization.
gcc/testsuite/ChangeLog:
* gfortran.dg/EXformat_3.F90: New test covering rounding for
KIND=4, 8, 10, and 16: clear round-up, ties-to-even (truncate
and round-up cases), carry propagation, and normalization.
* gfortran.dg/EXrounding.F90: New test checking the various
rounding modes for all kinds.
---From aecbdc74231df195c5e38a11c3f7eaaf3591a704 Mon Sep 17 00:00:00 2001
From: Jerry DeLisle <[email protected]>
Date: Sat, 23 May 2026 20:28:43 -0700
Subject: [PATCH] Fortran: [PR93727] Add EX format rounding for truncated hex
mantissa
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Implement proper rounding of the hex mantissa in write_ex when the
user specifies a d smaller than full precision. All Fortran ROUND=
modes are supported: ROUND_NEAREST (ties-to-even), ROUND_COMPATIBLE
(ties away from zero), ROUND_UP, ROUND_DOWN, and ROUND_ZERO.
ROUND_PROCDEFINED and ROUND_UNSPECIFIED default to ROUND_NEAREST on
IEEE 754 systems, consistent with the decimal format behaviour.
Carry propagation handles the case where incrementing a string of
trailing F hex digits reaches the integer digit; if that overflows
(F → 16) the output is normalized by setting the integer digit to 8
and incrementing the binary exponent by one.
Assisted by: Claude Sonnet 4.6
PR fortran/93727
libgfortran/ChangeLog:
* io/write.c (write_ex): Replace simple truncation with
rounding-aware logic respecting dtp round_status. Add carry
propagation and integer-digit normalization.
gcc/testsuite/ChangeLog:
* gfortran.dg/EXformat_3.F90: New test covering rounding for
KIND=4, 8, 10, and 16: clear round-up, ties-to-even (truncate
and round-up cases), carry propagation, and normalization.
* gfortran.dg/EXrounding.F90: New test checking the various
rounding modes for all kinds.
---
gcc/testsuite/gfortran.dg/EXformat_3.F90 | 157 ++++++++++++++++++
gcc/testsuite/gfortran.dg/EXrounding.F90 | 200 +++++++++++++++++++++++
libgfortran/io/write.c | 105 +++++++++++-
3 files changed, 461 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/gfortran.dg/EXformat_3.F90
create mode 100644 gcc/testsuite/gfortran.dg/EXrounding.F90
diff --git a/gcc/testsuite/gfortran.dg/EXformat_3.F90 b/gcc/testsuite/gfortran.dg/EXformat_3.F90
new file mode 100644
index 00000000000..8f3b8bd2a7f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/EXformat_3.F90
@@ -0,0 +1,157 @@
+! { dg-do run }
+! PR93727 Test EX format rounding of truncated hex mantissa.
+! Verifies ROUND_NEAREST (round-to-nearest ties-to-even) when the
+! user specifies a d less than full precision.
+program main
+ implicit none
+ call test04
+ call test08
+ call test10
+ call test16
+
+contains
+
+subroutine test04
+ real(kind=4) :: r4
+ character(kind=1,len=40) :: s
+
+ ! Carry propagates through all fractional digits into integer digit;
+ ! integer F overflows -> normalize to 8 with exponent incremented.
+ ! huge(1.0_4) = 0XF.FFFFFP+124
+ ! d=4: first dropped F > 8, all frac digits carry to 0, F+1 -> 8, exp 125
+ r4 = huge(1.0_4)
+ write(s, '(EX0.4)') r4
+ if (s(1:13) /= '0X8.0000P+125') stop 1
+
+end subroutine test04
+
+subroutine test08
+ real(kind=8) :: r8
+ character(kind=1,len=40) :: s
+
+ ! Round up: first dropped digit B (=11) > 8, with carry through F into D.
+ ! -pi*25 = -0X9.D14707B63DFBP+3 (12 significant frac digits, 13th = 0)
+ ! d=11 keeps D14707B63DF, first dropped B -> round up
+ ! last kept F + 1 = 0 carry, D + 1 = E, result: -0X9.D14707B63E0P+3
+ r8 = -3.14159682678_8 * 25._8
+ write(s, '(EX0.11)') r8
+ if (s(1:19) /= '-0X9.D14707B63E0P+3') stop 2
+
+ ! Tie, last kept digit even (C=12) -> truncate (round to even).
+ ! 10.736328125 = 0XA.BC8000000000P+0
+ ! d=2: first dropped 8, tail zeros, C even -> truncate -> 0XA.BCP+0
+ r8 = 10.736328125_8
+ write(s, '(EX0.2)') r8
+ if (s(1:9) /= '0XA.BCP+0') stop 3
+
+ ! Tie, last kept digit odd (B=11) -> round up (round to even).
+ ! 10.732421875 = 0XA.BB8000000000P+0
+ ! d=2: first dropped 8, tail zeros, B odd -> round up, B+1=C -> 0XA.BCP+0
+ r8 = 10.732421875_8
+ write(s, '(EX0.2)') r8
+ if (s(1:9) /= '0XA.BCP+0') stop 4
+
+ ! Round up: first dropped digit 9 > 8, no carry.
+ ! 10.736572265625 = 0XA.BC9000000000P+0
+ ! d=2: first dropped 9 > 8 -> round up, C+1=D -> 0XA.BDP+0
+ r8 = 10.736572265625_8
+ write(s, '(EX0.2)') r8
+ if (s(1:9) /= '0XA.BDP+0') stop 5
+
+end subroutine test08
+
+#ifdef __GFC_REAL_10__
+subroutine test10
+ real(kind=10) :: r10
+ character(kind=1,len=40) :: s
+
+ ! Tie, last kept digit even (C=12) -> truncate.
+ ! 10.736328125 = 0XA.BC8000000000000P+0 (15 frac digits)
+ ! d=2: first dropped 8, tail zeros, C even -> truncate -> 0XA.BCP+0
+ r10 = 10.736328125_10
+ write(s, '(EX0.2)') r10
+ if (s(1:9) /= '0XA.BCP+0') stop 6
+
+ ! Tie, last kept digit odd (B=11) -> round up.
+ ! 10.732421875 = 0XA.BB8000000000000P+0
+ ! d=2: first dropped 8, tail zeros, B odd -> round up -> 0XA.BCP+0
+ r10 = 10.732421875_10
+ write(s, '(EX0.2)') r10
+ if (s(1:9) /= '0XA.BCP+0') stop 7
+
+ ! Round up: first dropped digit 9 > 8, no carry.
+ ! 10.736572265625 = 0XA.BC9000000000000P+0
+ ! d=2: first dropped 9 > 8 -> round up, C+1=D -> 0XA.BDP+0
+ r10 = 10.736572265625_10
+ write(s, '(EX0.2)') r10
+ if (s(1:9) /= '0XA.BDP+0') stop 8
+
+ ! Round up: first dropped digit 9 > 8 in -pi*25 at d=13.
+ ! -pi*25 = -0X9.D14707B63DFB497P+3 (15 frac digits)
+ ! d=13: first dropped 9 > 8, last kept 4+1=5, no carry
+ ! result: -0X9.D14707B63DFB5P+3
+ r10 = -3.14159682678_10 * 25._10
+ write(s, '(EX0.13)') r10
+ if (s(1:21) /= '-0X9.D14707B63DFB5P+3') stop 9
+
+ ! Normalization: carry through all 14 frac digits into integer.
+ ! huge(1.0_10) = 0XF.FFFFFFFFFFFFFFFP+16380 (15 frac digits)
+ ! d=14: first dropped F > 8, all carry, F+1 -> 8, exp 16381
+ r10 = huge(1.0_10)
+ write(s, '(EX0.14)') r10
+ if (s(1:25) /= '0X8.00000000000000P+16381') stop 10
+
+end subroutine test10
+#else
+subroutine test10
+end subroutine test10
+#endif
+
+#ifdef __GFC_REAL_16__
+subroutine test16
+ real(kind=16) :: r16
+ character(kind=1,len=45) :: s
+
+ ! Tie, last kept digit even (C=12) -> truncate.
+ ! 10.736328125 = 0XA.BC8000000000000000000000000P+0 (28 frac digits)
+ ! d=2: first dropped 8, tail zeros, C even -> truncate -> 0XA.BCP+0
+ r16 = 10.736328125_16
+ write(s, '(EX0.2)') r16
+ if (s(1:9) /= '0XA.BCP+0') stop 11
+
+ ! Tie, last kept digit odd (B=11) -> round up.
+ ! 10.732421875 = 0XA.BB8000000000000000000000000P+0
+ ! d=2: first dropped 8, tail zeros, B odd -> round up -> 0XA.BCP+0
+ r16 = 10.732421875_16
+ write(s, '(EX0.2)') r16
+ if (s(1:9) /= '0XA.BCP+0') stop 12
+
+ ! Round up: first dropped digit 9 > 8, no carry.
+ ! 10.736572265625 = 0XA.BC9000000000000000000000000P+0
+ ! d=2: first dropped 9 > 8 -> round up, C+1=D -> 0XA.BDP+0
+ r16 = 10.736572265625_16
+ write(s, '(EX0.2)') r16
+ if (s(1:9) /= '0XA.BDP+0') stop 13
+
+ ! Round up at d=26 on 1/3 = 0XA.AAAAAAAAAAAAAAAAAAAAAAAAAAA8P-5
+ ! d=26: first dropped A (=10) > 8, last kept A+1=B, no carry
+ ! result: 0XA.AAAAAAAAAAAAAAAAAAAAAAAAABP-5
+ r16 = 1.0_16 / 3.0_16
+ write(s, '(EX0.26)') r16
+ if (s(1:33) /= '0XA.AAAAAAAAAAAAAAAAAAAAAAAAABP-5') stop 14
+
+ ! Tie and normalization: huge(1.0_16) = 0XF.FFFFFFFFFFFFFFFFFFFFFFFFFFF8P+16380
+ ! d=27: first dropped 8, tail empty -> tie, last kept F (odd) -> round up
+ ! all 27 F's carry, F+1 -> 8, exp 16381
+ ! result: 0X8.000000000000000000000000000P+16381
+ r16 = huge(1.0_16)
+ write(s, '(EX0.27)') r16
+ if (s(1:38) /= '0X8.000000000000000000000000000P+16381') stop 15
+
+end subroutine test16
+#else
+subroutine test16
+end subroutine test16
+#endif
+
+end program main
diff --git a/gcc/testsuite/gfortran.dg/EXrounding.F90 b/gcc/testsuite/gfortran.dg/EXrounding.F90
new file mode 100644
index 00000000000..a385343caba
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/EXrounding.F90
@@ -0,0 +1,200 @@
+! { dg-do run }
+! PR93727 Test EX format explicit rounding modes (ROUND_NEAREST, ROUND_UP,
+! ROUND_DOWN, ROUND_ZERO) for truncated hex mantissa, all supported kinds.
+!
+! Key values used throughout (all exactly representable):
+! 10.736328125 = 0XA.BC8000...P+0 tie at d=2, last kept C (12, even)
+! 10.732421875 = 0XA.BB8000...P+0 tie at d=2, last kept B (11, odd)
+! 10.736572265625 = 0XA.BC9000...P+0 dropped digit 9 > 8, no tie
+program main
+ implicit none
+ call test04_rounding
+ call test08_rounding
+ call test10_rounding
+ call test16_rounding
+
+contains
+
+! ---------------------------------------------------------------------------
+subroutine test04_rounding
+ real(kind=4) :: r4
+ character(kind=1,len=40) :: s
+
+ ! Positive tie, last kept even (C=12): RN truncates, RU rounds up.
+ r4 = 10.736328125_4
+ write(s, '(EX0.2)', round='nearest') r4
+ if (s(1:9) /= '0XA.BCP+0') stop 1
+ write(s, '(EX0.2)', round='up') r4
+ if (s(1:9) /= '0XA.BDP+0') stop 2
+ write(s, '(EX0.2)', round='down') r4
+ if (s(1:9) /= '0XA.BCP+0') stop 3
+ write(s, '(EX0.2)', round='zero') r4
+ if (s(1:9) /= '0XA.BCP+0') stop 4
+
+ ! Positive tie, last kept odd (B=11): RN rounds up.
+ r4 = 10.732421875_4
+ write(s, '(EX0.2)', round='nearest') r4
+ if (s(1:9) /= '0XA.BCP+0') stop 5
+
+ ! Positive: dropped digit 9 > 8, no tie; all modes with dropped nonzero round up.
+ r4 = 10.736572265625_4
+ write(s, '(EX0.2)', round='nearest') r4
+ if (s(1:9) /= '0XA.BDP+0') stop 6
+ write(s, '(EX0.2)', round='up') r4
+ if (s(1:9) /= '0XA.BDP+0') stop 7
+ write(s, '(EX0.2)', round='zero') r4
+ if (s(1:9) /= '0XA.BCP+0') stop 8
+
+ ! Negative tie, last kept even (C=12): RD rounds up in magnitude.
+ r4 = -10.736328125_4
+ write(s, '(EX0.2)', round='nearest') r4
+ if (s(1:10) /= '-0XA.BCP+0') stop 9
+ write(s, '(EX0.2)', round='down') r4
+ if (s(1:10) /= '-0XA.BDP+0') stop 10
+ write(s, '(EX0.2)', round='up') r4
+ if (s(1:10) /= '-0XA.BCP+0') stop 11
+ write(s, '(EX0.2)', round='zero') r4
+ if (s(1:10) /= '-0XA.BCP+0') stop 12
+
+end subroutine test04_rounding
+
+! ---------------------------------------------------------------------------
+subroutine test08_rounding
+ real(kind=8) :: r8
+ character(kind=1,len=40) :: s
+
+ ! Positive tie, last kept even (C=12).
+ r8 = 10.736328125_8
+ write(s, '(EX0.2)', round='nearest') r8
+ if (s(1:9) /= '0XA.BCP+0') stop 13
+ write(s, '(EX0.2)', round='up') r8
+ if (s(1:9) /= '0XA.BDP+0') stop 14
+ write(s, '(EX0.2)', round='down') r8
+ if (s(1:9) /= '0XA.BCP+0') stop 15
+ write(s, '(EX0.2)', round='zero') r8
+ if (s(1:9) /= '0XA.BCP+0') stop 16
+
+ ! Positive tie, last kept odd (B=11): RN rounds up.
+ r8 = 10.732421875_8
+ write(s, '(EX0.2)', round='nearest') r8
+ if (s(1:9) /= '0XA.BCP+0') stop 17
+
+ ! Positive: dropped digit 9 > 8.
+ r8 = 10.736572265625_8
+ write(s, '(EX0.2)', round='nearest') r8
+ if (s(1:9) /= '0XA.BDP+0') stop 18
+ write(s, '(EX0.2)', round='up') r8
+ if (s(1:9) /= '0XA.BDP+0') stop 19
+ write(s, '(EX0.2)', round='zero') r8
+ if (s(1:9) /= '0XA.BCP+0') stop 20
+
+ ! Negative tie, last kept even (C=12).
+ r8 = -10.736328125_8
+ write(s, '(EX0.2)', round='nearest') r8
+ if (s(1:10) /= '-0XA.BCP+0') stop 21
+ write(s, '(EX0.2)', round='down') r8
+ if (s(1:10) /= '-0XA.BDP+0') stop 22
+ write(s, '(EX0.2)', round='up') r8
+ if (s(1:10) /= '-0XA.BCP+0') stop 23
+ write(s, '(EX0.2)', round='zero') r8
+ if (s(1:10) /= '-0XA.BCP+0') stop 24
+
+end subroutine test08_rounding
+
+! ---------------------------------------------------------------------------
+#ifdef __GFC_REAL_10__
+subroutine test10_rounding
+ real(kind=10) :: r10
+ character(kind=1,len=40) :: s
+
+ ! Positive tie, last kept even (C=12).
+ r10 = 10.736328125_10
+ write(s, '(EX0.2)', round='nearest') r10
+ if (s(1:9) /= '0XA.BCP+0') stop 25
+ write(s, '(EX0.2)', round='up') r10
+ if (s(1:9) /= '0XA.BDP+0') stop 26
+ write(s, '(EX0.2)', round='down') r10
+ if (s(1:9) /= '0XA.BCP+0') stop 27
+ write(s, '(EX0.2)', round='zero') r10
+ if (s(1:9) /= '0XA.BCP+0') stop 28
+
+ ! Positive tie, last kept odd (B=11): RN rounds up.
+ r10 = 10.732421875_10
+ write(s, '(EX0.2)', round='nearest') r10
+ if (s(1:9) /= '0XA.BCP+0') stop 29
+
+ ! Positive: dropped digit 9 > 8.
+ r10 = 10.736572265625_10
+ write(s, '(EX0.2)', round='nearest') r10
+ if (s(1:9) /= '0XA.BDP+0') stop 30
+ write(s, '(EX0.2)', round='up') r10
+ if (s(1:9) /= '0XA.BDP+0') stop 31
+ write(s, '(EX0.2)', round='zero') r10
+ if (s(1:9) /= '0XA.BCP+0') stop 32
+
+ ! Negative tie, last kept even (C=12).
+ r10 = -10.736328125_10
+ write(s, '(EX0.2)', round='nearest') r10
+ if (s(1:10) /= '-0XA.BCP+0') stop 33
+ write(s, '(EX0.2)', round='down') r10
+ if (s(1:10) /= '-0XA.BDP+0') stop 34
+ write(s, '(EX0.2)', round='up') r10
+ if (s(1:10) /= '-0XA.BCP+0') stop 35
+ write(s, '(EX0.2)', round='zero') r10
+ if (s(1:10) /= '-0XA.BCP+0') stop 36
+
+end subroutine test10_rounding
+#else
+subroutine test10_rounding
+end subroutine test10_rounding
+#endif
+
+! ---------------------------------------------------------------------------
+#ifdef __GFC_REAL_16__
+subroutine test16_rounding
+ real(kind=16) :: r16
+ character(kind=1,len=40) :: s
+
+ ! Positive tie, last kept even (C=12).
+ r16 = 10.736328125_16
+ write(s, '(EX0.2)', round='nearest') r16
+ if (s(1:9) /= '0XA.BCP+0') stop 37
+ write(s, '(EX0.2)', round='up') r16
+ if (s(1:9) /= '0XA.BDP+0') stop 38
+ write(s, '(EX0.2)', round='down') r16
+ if (s(1:9) /= '0XA.BCP+0') stop 39
+ write(s, '(EX0.2)', round='zero') r16
+ if (s(1:9) /= '0XA.BCP+0') stop 40
+
+ ! Positive tie, last kept odd (B=11): RN rounds up.
+ r16 = 10.732421875_16
+ write(s, '(EX0.2)', round='nearest') r16
+ if (s(1:9) /= '0XA.BCP+0') stop 41
+
+ ! Positive: dropped digit 9 > 8.
+ r16 = 10.736572265625_16
+ write(s, '(EX0.2)', round='nearest') r16
+ if (s(1:9) /= '0XA.BDP+0') stop 42
+ write(s, '(EX0.2)', round='up') r16
+ if (s(1:9) /= '0XA.BDP+0') stop 43
+ write(s, '(EX0.2)', round='zero') r16
+ if (s(1:9) /= '0XA.BCP+0') stop 44
+
+ ! Negative tie, last kept even (C=12).
+ r16 = -10.736328125_16
+ write(s, '(EX0.2)', round='nearest') r16
+ if (s(1:10) /= '-0XA.BCP+0') stop 45
+ write(s, '(EX0.2)', round='down') r16
+ if (s(1:10) /= '-0XA.BDP+0') stop 46
+ write(s, '(EX0.2)', round='up') r16
+ if (s(1:10) /= '-0XA.BCP+0') stop 47
+ write(s, '(EX0.2)', round='zero') r16
+ if (s(1:10) /= '-0XA.BCP+0') stop 48
+
+end subroutine test16_rounding
+#else
+subroutine test16_rounding
+end subroutine test16_rounding
+#endif
+
+end program main
diff --git a/libgfortran/io/write.c b/libgfortran/io/write.c
index 44f4b614c4f..3b187c61843 100644
--- a/libgfortran/io/write.c
+++ b/libgfortran/io/write.c
@@ -1955,9 +1955,112 @@ write_ex (st_parameter_dt *dtp, const fnode *f, const char *p, int kind)
/* Adjust mantissa to have exactly 'd' digits after decimal */
if (d < mantissa_digits)
{
- /* Truncate mantissa */
+ /* Determine rounding direction before truncating. */
+ char *first_drop = decimal + d + 1;
+ char fc = *first_drop;
+ int fd_val = (fc >= '0' && fc <= '9') ? fc - '0'
+ : (fc >= 'A' && fc <= 'F') ? fc - 'A' + 10 : 0;
+
+ /* Check whether any tail digits (beyond the
+ first dropped digit) are nonzero. */
+ bool tail_nonzero = false;
+ for (char *tp = first_drop + 1; tp < p_pos; tp++)
+ if (*tp != '0')
+ {
+ tail_nonzero = true;
+ break;
+ }
+
+ bool is_negative = (buf[0] == '-');
+ bool do_round_up = false;
+
+ switch (dtp->u.p.current_unit->round_status)
+ {
+ case ROUND_ZERO:
+ /* Truncate toward zero; no adjustment needed. */
+ break;
+ case ROUND_UP:
+ /* Toward +inf: round up positive values only. */
+ if (!is_negative && (fd_val > 0 || tail_nonzero))
+ do_round_up = true;
+ break;
+ case ROUND_DOWN:
+ /* Toward -inf: round up negative values only. */
+ if (is_negative && (fd_val > 0 || tail_nonzero))
+ do_round_up = true;
+ break;
+ case ROUND_COMPATIBLE:
+ /* Nearest, ties away from zero. */
+ do_round_up = (fd_val >= 8);
+ break;
+ case ROUND_PROCDEFINED:
+ case ROUND_UNSPECIFIED:
+ /* Processor-defined defaults to ROUND_NEAREST on IEEE 754
+ systems. Fall through. */
+ default:
+ case ROUND_NEAREST:
+ /* Round to nearest, ties to even. */
+ if (fd_val > 8)
+ do_round_up = true;
+ else if (fd_val == 8)
+ {
+ if (tail_nonzero)
+ do_round_up = true;
+ else
+ {
+ /* Exact tie: round last kept digit to even. */
+ char lk = *(decimal + d);
+ int lk_val = (lk >= '0' && lk <= '9') ? lk - '0'
+ : lk - 'A' + 10;
+ do_round_up = (lk_val & 1) != 0;
+ }
+ }
+ break;
+ }
+
+ /* Truncate the fractional part to d digits. */
memmove (decimal + d + 1, p_pos, strlen (p_pos) + 1);
p_pos = decimal + d + 1;
+
+ if (do_round_up)
+ {
+ /* Propagate carry leftward through the fractional digits. */
+ char *pos = p_pos - 1;
+ while (pos > decimal)
+ {
+ int dv = (*pos >= '0' && *pos <= '9') ? *pos - '0'
+ : *pos - 'A' + 10;
+ dv++;
+ if (dv < 16)
+ {
+ *pos = dv < 10 ? ('0' + dv) : ('A' + dv - 10);
+ goto rounding_done;
+ }
+ *pos = '0';
+ pos--;
+ }
+ /* Carry reached the integer digit (at decimal - 1). */
+ pos = decimal - 1;
+ {
+ int dv = (*pos >= '0' && *pos <= '9') ? *pos - '0'
+ : *pos - 'A' + 10;
+ dv++;
+ if (dv < 16)
+ *pos = dv < 10 ? ('0' + dv) : ('A' + dv - 10);
+ else
+ {
+ /* Integer digit overflowed (was F). Normalize: the
+ value F.0...0 * 2^exp to 8.0...0 * 2^(exp+1). */
+ *pos = '8';
+ int actual_exp = (sign_char == '-') ? -(int)exp_value
+ : (int)exp_value;
+ actual_exp++;
+ exp_value = actual_exp >= 0 ? actual_exp : -actual_exp;
+ sign_char = actual_exp >= 0 ? '+' : '-';
+ }
+ }
+ rounding_done:;
+ }
}
else if (d > mantissa_digits)
{
--
2.54.0