Solved

C format specifer for doubles with leading 0's

Posted on 2014-04-14
12
334 Views
Last Modified: 2014-05-07
In C:

The following statement (for a value of 12345.67 for a double:
printf("that is 09.2f: <%09.2f>\n", double_dollar_amount_with_cents);

outputs:
"that is 09.2f: < 12345.67>"

Why am I not getting the leading 0 likeI would for something like "%05ld"? Is it not supported for floats on all compilers?

Thanks,
Steve
0
Comment
Question by:Stephen Kairys
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 4
  • 2
12 Comments
 
LVL 84

Expert Comment

by:ozo
ID: 40000337
It may be reserving space for a - sign.
Did you try
printf("that is 09.2f: <%09.2f>\n", 123.45);
or
printf("that is 011.2f: <%011.2f>\n", 12345.67);
0
 
LVL 45

Assisted Solution

by:Kent Olsen
Kent Olsen earned 150 total points
ID: 40000339
Hi Steve,

That looks like really bizarre behavior to me.  I would expect the results to be "012345.67".

Two quick things.

(I hate to ask this one.)  Are you sure that you're testing with "09.2f"?

Try it again with a larger format specifier.  "%010.2f" or "012.2f".  Or pass a value with fewer digits to the current test.  I'm wondering if the formatting might be forcing 1 space.


Kent
0
 
LVL 4

Author Comment

by:Stephen Kairys
ID: 40000389
Ozo and Kent - thanks for the quick reply.  I tried the below with the same odd behavior.

printf("HARDCODED:that is 09.2f: <%09.2f>\n", 123.45);
printf("HARDCODED:that is 011.2f: <%011.2f>\n", 12345.67);
------------------------
HARDCODED:that is 09.2f: <   123.45>
HARDCODED:that is 011.2f: <   12345.67>

FWIW, this is the WATCOM 11 compiler.
Steve
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 84

Assisted Solution

by:ozo
ozo earned 350 total points
ID: 40000414
it looks to me like the WATCOM 11 compiler is not confoming to the ISO/IEC standard
0
 
LVL 4

Author Comment

by:Stephen Kairys
ID: 40000459
Well that was interesting...and fun. :)

I found this paragraph per this link. The emphasis is mine and I have added whitespace for readabiliy.

http://www.openwatcom.org/ftp/manuals/current/clib.pdf

"If no field width is specified, or if the value that is given is less than the number of characters in the converted value (subject to any precision value), a field of sufficient width to contain the converted value is used.  

"If the converted value has fewer characters than are specified by the field width, the value is padded on the left (or right, subject to the left-justification flag) with spaces or zero characters ("0").

" If the field width begins with "0" and no precision is specified, the value is padded with zeros; otherwise the value is padded with spaces.  

"If the field width is "*", a value of type int from the argument list is used (before a precision argument or a conversion argument) as the minimum field width.  A negative field width value is interpreted as a left-justification flag, followed by a positive field width."

So, per the above, do you still say that this is NOT per the ISO/IEC standard?
Thanks.
Steve
0
 
LVL 84

Expert Comment

by:ozo
ID: 40000553
ISO/IEC says

0 For d, i, o, u, x, X, a, A, e, E, f, F, g, and G conversions, leading zeros
(following any indication of sign or base) are used to pad to the field width rather
than performing space padding, except when converting an infinity or NaN. If the
0 and - flags both appear, the 0 flag is ignored. For d, i, o, u, x, and X
conversions, if a precision is specified, the 0 flag is ignored. For other
conversions, the behavior is undefined.
0
 
LVL 4

Author Comment

by:Stephen Kairys
ID: 40000784
OK, thanks for posting this. So if I understand correctly, the above says that my compler does NOT adhere to the standard, right?

That said, I suppose there would be a workaround. This is actually an sprintf() to build a key that has 4 components, one of them a double.

So I suppose I could say:

for (count = 0; count < strlen(buffer), ++count)
{
  if buffer[count] == ' '
    buffer[count] = '0'.
}

Thanks again.
0
 
LVL 84

Accepted Solution

by:
ozo earned 350 total points
ID: 40000844
I'd say that you can sprintf with space padding, then convert spaces to 0, except that with
negative numbers, I'd expect that WATCOM would put the spaces before the - instead of
0's after the -, which is what I understand the standard to be specifying.

Or, if WATCOM does do 0 padding when no precision is specified, then maybe you can handle the .67 part separately.  (Which may be a good practice anyway if you are trying to handle exact decimal quantities like money using approximate floating values)
0
 
LVL 4

Author Comment

by:Stephen Kairys
ID: 40001604
Ozo,

Our data will not have negative numbers. Each entry is the total price of items requested by a customer.   We are actually storing as implied decimal. e.g. $12.34 is 1234. You may ask why we don't use longs (32-bit)?  Reason is that the limit of 4 billion and change means we could not go over $40 million and change.

FWIW, you are write about padding for negatives:
 
e.g.
HARDCODED:that is 011.2f: <  -12345.67>

Thanks...this has been a fascinating discussion. ;)
0
 
LVL 45

Expert Comment

by:Kent Olsen
ID: 40001637
Hi Steve,

printf, fprintf, and sprintf return the number of characters written.  It's kinda ugly, but since negative numbers aren't an issue to you, that can be used to roll-your-own leading zeros.

      float V = 12345.67;
      char Buffer[20];
      int Length;

      Length = sprintf (Buffer, "%.2f", V);
      printf ("%*.*s%s", 9-Length, 9-Length, "000000000", Buffer);
      return 0;

Sanity checks to ensure that the value of 9-Length is in range is a good idea.   :)


Good Luck,
Kent
0
 
LVL 4

Author Comment

by:Stephen Kairys
ID: 40001647
Kent,
Haven't tried this but, to the naked eye, looks pretty slick. Thanks.
0
 
LVL 4

Author Closing Comment

by:Stephen Kairys
ID: 40047544
Thanks, everyone for the help. I ended up using the FOR loop to convert my spaces to zeroes.
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
How do I install gcc 4.8.4 on a Linux Ubuntu 14.04 machine? 5 2,317
Acrinis True image 2 118
gdb doesn't stop on breakpoint 2 133
How to install SVN Command Line Client? 5 128
Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to create, access, and change arrays in the C programming language.

738 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question