Bug 2194 - printf: meaning of precision for 'd', 'i', 'o', 'u', 'x', 'X' directives
Summary: printf: meaning of precision for 'd', 'i', 'o', 'u', 'x', 'X' directives
Status: RESOLVED INVALID
Alias: None
Product: glibc
Classification: Unclassified
Component: libc (show other bugs)
Version: 2.3.6
: P2 normal
Target Milestone: ---
Assignee: Ulrich Drepper
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-01-23 15:11 UTC by Bruno Haible
Modified: 2018-04-19 13:59 UTC (History)
1 user (show)

See Also:
Host: i686-pc-linux-gnu
Target: i686-pc-linux-gnu
Build: i686-pc-linux-gnu
Last reconfirmed:
fweimer: security-


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Bruno Haible 2006-01-23 15:11:49 UTC
Hi, 
 
In a printf(3) format directive such as "%.10d", what does the precision 10 
mean? ISO C 99 section 7.19.6.1. paragraphs 4 and 8, and POSIX 
(http://www.opengroup.org/susv3/functions/fprintf.html) both say: 
 
  "The precision specifies the minimum number of digits to appear; 
   if the value being converted can be represented in fewer digits, 
   it is expanded with leading zeros." 
 
Here is a test program: 
 
========================================= 
#include <locale.h> 
#include <stdio.h> 
int main () 
{ 
  setlocale(LC_ALL,""); 
  printf("%#'.10d\n", 1); 
  printf("%#'.10d\n", 12); 
  printf("%#'.10d\n", 123); 
  printf("%#'.10d\n", 1234); 
  printf("%#'.10d\n", 12345); 
  printf("%#'.10d\n", 123456); 
  printf("%#'.10d\n", 1234567); 
  printf("%#'.10d\n", 12345678); 
  printf("%#'.10d\n", 123456789); 
  printf("%#'.10lld\n", 1234567890LL); 
  printf("%#'.10lld\n", 12345678901LL); 
  printf("%#'.10lld\n", 123456789012LL); 
  return 0; 
} 
========================================= 
 
Output in the C locale in glibc-2.3.6 is as expected: 
 
0000000001 
0000000012 
0000000123 
0000001234 
0000012345 
0000123456 
0001234567 
0012345678 
0123456789 
1234567890 
12345678901 
123456789012 
 
Output in the de_DE.UTF-8 locale in glibc-2.3.6: 
 
0000000001 
0000000012 
0000000123 
000001.234 
000012.345 
000123.456 
01.234.567 
12.345.678 
123.456.789 
1.234.567.890 
12.345.678.901 
123.456.789.012 
 
Expected output according to POSIX: 
 
0.000.000.001 
0.000.000.012 
0.000.000.123 
0.000.001.234 
0.000.012.345 
0.000.123.456 
0.001.234.567 
0.012.345.678 
0.123.456.789 
1.234.567.890 
12.345.678.901 
123.456.789.012 
 
As you can see, glibc has interpreted the precision 10 as if a _width_ of 10 
was specified, with leading 0, but because of the thousands grouping it should 
translate to a width of 13.
Comment 1 Andreas Schwab 2006-01-23 15:35:21 UTC
Subject: Re:  New: printf: meaning of precision for 'd', 'i', 'o', 'u', 'x', 'X' directives

"bruno at clisp dot org" <sourceware-bugzilla@sourceware.org> writes:

> Expected output according to POSIX: 
>  
> 0.000.000.001 
> 0.000.000.012 
> 0.000.000.123 
> 0.000.001.234 
> 0.000.012.345 
> 0.000.123.456 
> 0.001.234.567 
> 0.012.345.678 
> 0.123.456.789 
> 1.234.567.890 
> 12.345.678.901 
> 123.456.789.012 

Why do you think the grouping characters should be inserted after the
padding?  POSIX says in the description of the '0' flag:

    If the ’0’ and ’’’ flags both appear, the grouping characters are
    inserted before zero padding.

Andreas.

Comment 2 Bruno Haible 2006-01-23 15:49:05 UTC
> Why do you think the grouping characters should be inserted after the 
> padding? 
 
The bug report is not about padding: I didn't specify a width. I specified 
a precision, and the POSIX explanation of precision talks about the 
"number of digits", not about padding. 
 
> POSIX says in the description of the '0' flag: 
 
A '0' flag is not specified in the sample program above. 
 
Comment 3 Andreas Schwab 2006-01-23 16:45:51 UTC
(In reply to comment #2) 
> > Why do you think the grouping characters should be inserted after the  
> > padding?  
>   
> The bug report is not about padding: I didn't specify a width. 
 
The precision and the width are the same concepts, only with different effects 
on the effective field width. Precision padding is still padding. 
 
> I specified  
> a precision, and the POSIX explanation of precision talks about the  
> "number of digits", not about padding.  
 
The number of digits is achieved by padding it with zero. 
 
> > POSIX says in the description of the '0' flag:  
>   
> A '0' flag is not specified in the sample program above.  
 
That is true, but the concepts are the same. The formatting in your case 
should be consistent with that. 
Comment 4 Bruno Haible 2006-01-23 17:29:46 UTC
(In reply to comment #3) 
> The precision and the width are the same concepts 
 
They are the same concepts for the %s and %S conversion specifiers, not for 
the others. See http://www.opengroup.org/susv3/functions/fprintf.html 
 
> The number of digits is achieved by padding it with zero.  
 
The sample program specifies a precision of 10. According to POSIX the 
precision is the minimum amount of digits. Yet glibc outputs strings like 
"01.234.567" which has only 8 digits. 
 
Comment 5 Ulrich Drepper 2006-02-03 22:04:41 UTC
I completely disagree that there is anything wrong.  Not only is the existing
behavior common practice, it's also tested like this in various test suites.

If you disagree, get *first* a resolution on this from the Austin Group.  Do not
think about reopening before you get that.