Tcl Source Code

View Ticket
Login
Ticket UUID: 2dff98e0791720bdde656d47762553c1089684a4
Title: format %A garbles negative, padded and infinite values
Type: Bug Created on: 2026-10-16 22:13:57
Submitter: serhiy.storchaka Assigned to: jan.nijtmans
Subsystem: 16. Commands A-H Severity: Minor
Priority: 5 Medium Last modified: 2026-10-18 21:07:22
Status: Closed Closed by: jan.nijtmans
Resolution: Fixed Closed on: 2026-10-18 21:07:22
Version: 9.0.5, 9.1.0
Description:

[format %A] overwrites the second character of the result with "x", assuming that it starts with "0X":

format %A -1.5    ;# -xX1.8p+0
format %+A 1.0    ;# +xX1p+0
format %10A 1.5   ;#  x0X1.8p+0
format %A Inf     ;# IxF

Only plain positive values come out right (0x1.8p+0). The code came with %a/%A in [5cfe15b5d6].

User Comments:
serhiy.storchaka added on 2026-10-16 22:18:07:

Proposed fix in branch format-A-prefix: lowercase the "0X" prefix and the "P" exponent marker where they are, which is after the padding and the sign, and leave INF alone. Test format-19.5.


jan.nijtmans added on 2026-10-17 06:54:38:

+1

Please go ahead


serhiy.storchaka added on 2026-10-17 07:25:45:

Merged into main in [9336b96c43] and into 9.0 in [06f25062c2].


jan.nijtmans added on 2026-10-18 08:53:28:

Just one thing left to fix. With msvcrt (not ucrt):

==== format-19.5 %A with sign, padding and Inf, bug [2dff98e079] FAILED
==== Contents of test case:

# explicit precision: without it MSVC prints all 13 hex digits list [format %.1A 1.5] [format %.1A -1.5] [format %+.0A 1.0] [format "% .0A" 1.0] [format %10.1A 1.5] [format %-10.0A| -2.0] [format %A Inf] [format %A -Inf]

---- Result was: 0x1.8p+0 -0x1.8p+0 +0x1p+0 { 0x1p+0} { 0x1.8p+0} {-0x1p+1 |} 0x1.#INF00p+0 -0x1.#INF00p+0 ---- Result should have been (exact matching): 0x1.8p+0 -0x1.8p+0 +0x1p+0 { 0x1p+0} { 0x1.8p+0} {-0x1p+1 |} INF -INF ==== format-19.5 FAILED

Matching with -glob would be easiest: If it contains 'INF' that should be OK


jan.nijtmans added on 2026-10-18 08:59:20:

My proposal [6715b0e7eddf95f|here] (unless someone has a better idea)


jan.nijtmans added on 2026-10-18 08:59:32:

My proposal [6715b0e7eddf95f|here] (unless someone has a better idea)


jan.nijtmans added on 2026-10-18 09:00:57:

My proposal [96715b0e7e|here] (unless someone has a better idea)


serhiy.storchaka added on 2026-10-18 09:21:47:

Another option, done in [f5bb9702a9]: format infinities ourselves instead of passing them to the C library, as Python does. msvcrt gets them wrong for all float conversions, not only %A (1.#INF00e+000, 1.#INF even for %G). Now they are inf or INF (for %A, %E, %G) with the sign flags, padded with spaces, as C99 specifies; the output on glibc and ucrt does not change. format-19.5 is exact again, new test format-19.6. Tested with a mingw msvcrt build on Windows 11: format.test passes, and fails without this change. NaN cannot get there, it is rejected earlier.


jan.nijtmans added on 2026-10-18 21:07:22:

Agreed! Follow-up patch now merged too.

Thanks!