[libc-commits] [PATCH] D156489: [libc] Fix printf g conversion with high precision
Michael Jones via Phabricator via libc-commits
libc-commits at lists.llvm.org
Fri Jul 28 14:07:20 PDT 2023
This revision was automatically updated to reflect the committed changes.
Closed by commit rG63f8922f49b2: [libc] Fix printf g conversion with high precision (authored by michaelrj).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D156489/new/
https://reviews.llvm.org/D156489
Files:
libc/src/stdio/printf_core/float_dec_converter.h
libc/test/src/stdio/sprintf_test.cpp
Index: libc/test/src/stdio/sprintf_test.cpp
===================================================================
--- libc/test/src/stdio/sprintf_test.cpp
+++ libc/test/src/stdio/sprintf_test.cpp
@@ -2437,6 +2437,10 @@
written = __llvm_libc::sprintf(buff, "%.3g", 1256.0);
ASSERT_STREQ_LEN(written, buff, "1.26e+03");
+ // Found through large scale testing.
+ written = __llvm_libc::sprintf(buff, "%.15g", 22.25);
+ ASSERT_STREQ_LEN(written, buff, "22.25");
+
// Subnormal Precision Tests
written = __llvm_libc::sprintf(buff, "%.310g", 0x1.0p-1022);
Index: libc/src/stdio/printf_core/float_dec_converter.h
===================================================================
--- libc/src/stdio/printf_core/float_dec_converter.h
+++ libc/src/stdio/printf_core/float_dec_converter.h
@@ -965,15 +965,6 @@
if (digits_checked == 0) {
last_block_size = int_to_str.size();
implicit_leading_zeroes = 0;
- } else {
- // If the block is not the maximum size, that means it has leading
- // zeroes, and zeroes are not nines.
- if (implicit_leading_zeroes > 0) {
- trailing_nines = 0;
- }
-
- // But leading zeroes are zeroes (that could be trailing).
- trailing_zeroes += implicit_leading_zeroes;
}
int digits_requested = (exp_precision + 1) - digits_checked;
@@ -983,6 +974,19 @@
digits_to_check = 0;
}
+ // If the block is not the maximum size, that means it has leading
+ // zeroes, and zeroes are not nines.
+ if (implicit_leading_zeroes > 0) {
+ trailing_nines = 0;
+ }
+
+ // But leading zeroes are zeroes (that could be trailing). We take the
+ // minimum of the leading zeroes and digits requested because if there are
+ // more requested digits than leading zeroes we shouldn't count those.
+ trailing_zeroes +=
+ (implicit_leading_zeroes > digits_requested ? digits_requested
+ : implicit_leading_zeroes);
+
// Check the upper digits of this block.
for (int i = 0; i < digits_to_check; ++i) {
if (int_to_str[i] == '9') {
@@ -1103,6 +1107,24 @@
} else {
// If alt form isn't set, then we need to determine the number of trailing
// zeroes and set the precision such that they are removed.
+
+ /*
+ Here's a diagram of an example:
+
+ printf("%.15g", 22.25);
+
+ +--- init_precision = 15
+ |
+ +-------------------+
+ | |
+ | ++--- trimmed_precision = 2
+ | || |
+ 22.250000000000000000
+ || | |
+ ++ +--------------+
+ | |
+ base_10_exp + 1 = 2 --+ +--- trailing_zeroes = 11
+ */
int trimmed_precision =
digits_checked - (base_10_exp + 1) - trailing_zeroes;
if (trimmed_precision < 0) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D156489.545275.patch
Type: text/x-patch
Size: 3028 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libc-commits/attachments/20230728/c56ead83/attachment.bin>
More information about the libc-commits
mailing list