镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

Fixes #239: Limit the precision again when %g falls back to decimal mode - #240

Merged
eyalroz merged 0 commit into
eyalroz:developfrom
emincan2000:fix-g-precision-overflow
Oct 27, 2026
Merged

eyalroz merged 0 commit into
eyalroz:developfrom
emincan2000:fix-g-precision-overflow

Conversation

@emincan2000

Copy link
Copy Markdown

Fixes #239.

When %g falls back to decimal mode in print_exponential_number(), the precision becomes precision - floored_exp10, which for small values goes past PRINTF_MAX_SUPPORTED_PRECISION. This limits it again right there, the same way print_floating_point() does. Trailing zeros are only added with #, because without it %g drops trailing zeros, and the zeros put in buf up front wouldn't be dropped.

After the change:

"%.16g"  0.0001    -> 0.0001
"%.16g"  0.000123  -> 0.000123
"%#.16g" 0.001     -> 0.001000000000000000
"%.15g"  0.000338938832258952 -> 0.00033893883225895   (glibc: 0.000338938832258952)

The last one is still shorter than glibc's output, because only 17 decimals are available, but before it printed 0.

Testing:

  • Added the first three cases to avoiding_undefined_behavior. They fail without the change; test_suite passes with it (581 assertions on develop).
  • Ran 900k random format strings and values (d/i/u/o/x/X with length modifiers, f/e/E/g/G, s, c, with random flags/width/precision up to 15) against glibc under ASan/UBSan: no reports. Compared with the unpatched library, every output that changed was one of these out-of-bounds cases, and none of them got further from glibc's output.

PRINTING_CHECK("0.0001", ==, sprintf_, buffer, "%.16g", 0.0001);
PRINTING_CHECK("0.000123", ==, sprintf_, buffer, "%.16g", 0.000123);
PRINTING_CHECK("0.001000000000000000", ==, sprintf_, buffer, "%#.16g", 0.001);
}

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What made you choose to skip the fourth check from the bug, here? Is it redundant?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not redundant, it just doesn't pass yet. With the fix %.15g of 0.000338938832258952 prints 0.00033893883225895, while the correct output is 0.000338938832258952: after the fallback that needs 18 decimals, and we only have 17. So a check with the correct value would fail, and checking for the current output would lock in the truncated result.

I could add it commented out, like the beyond-precision checks in tiny_floating_point_values, or check that the output at least starts with 0.000338938832258 (i.e. not 0 anymore). Which would you prefer?

@eyalroz
eyalroz force-pushed the develop branch 2 times, most recently from efadbc9 to 07f977d Compare October 26, 2026 21:40
@eyalroz
eyalroz merged commit b0490d3 into eyalroz:develop Oct 27, 2026
@eyalroz

eyalroz commented Oct 27, 2026

Copy link
Copy Markdown
Owner

Tweaking the comments and the testcase after the merge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants