[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