Problem with printf formats

Discussion in 'C Programming' started by Guenther Sohler, Dec 20, 2005.

  1. I have following code:

    int main(void)
    {
    printf("%.3lf\n",-2158470*0.001);
    }

    it prints

    -2158.470

    How can i disable '0' at the end, if they are not needed ?

    Is there a possibility just to write %lf and just print as many digits
    as needed to represent the number ?
     
    Guenther Sohler, Dec 20, 2005
    #1
    1. Advertising

  2. Guenther Sohler

    Chuck F. Guest

    Guenther Sohler wrote:
    >
    > I have following code:
    >
    > int main(void)
    > {
    > printf("%.3lf\n",-2158470*0.001);
    > }
    >
    > it prints
    >
    > -2158.470
    >
    > How can i disable '0' at the end, if they are not needed ?
    >
    > Is there a possibility just to write %lf and just print as many
    > digits as needed to represent the number ?


    You are asking the wrong question. The trailing zero is needed to
    represent the number. Otherwise how could you distinguish it from:

    printf("%.2f\n", -2158471 * 0.001)

    (always assuming that -2158471 does not create an overflow)

    Your question, I believe, is "how to suppress trailing zeroes". A
    little thought and an intermediary buffer should give you a
    suitable answer for that.

    --
    A: Because it fouls the order in which people normally read text.
    Q: Why is top-posting such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Chuck F., Dec 20, 2005
    #2
    1. Advertising

  3. Guenther Sohler

    Guest

    Guenther Sohle said:
    >

    (...)
    > printf("%.3lf\n",-2158470*0.001);

    (...)
    > it prints
    >
    > -2158.470
    >
    > How can i disable '0' at the end, if they are not needed ? Is there a
    > possibility just to write %lf and just print as many digits as needed to
    > represent the number ?


    The problem is not in the printf() function, but in the way floating point
    numbers are represented by your computer. Due to rounding errors, floating
    point numbers hardly ever have the 'exact' value you would expect. Search
    google for 'floating point' for some details, or read this wikipedia page:
    http://en.wikipedia.org/wiki/Floating_point.

    It is up to you to make the choice how many digits are significant in a
    number, so that is why you should tell printf() about this.


    --
    :wq
    ^X^Cy^K^X^C^C^C^C
     
    , Dec 20, 2005
    #3
  4. Guenther Sohler

    Jirka Klaue Guest

    Guenther Sohler:

    > int main(void)
    > {
    > printf("%.3lf\n",-2158470*0.001);
    > }
    >
    > it prints
    >
    > -2158.470
    >
    > How can i disable '0' at the end, if they are not needed ?
    >
    > Is there a possibility just to write %lf and just print as many digits
    > as needed to represent the number ?


    The l in %lf is superfluous, just use %f.
    To avoid the trailing zeros try %g.

    Jirka
     
    Jirka Klaue, Dec 20, 2005
    #4
  5. On Tue, 20 Dec 2005 13:56:44 +0100, Jirka Klaue wrote:

    > Guenther Sohler:
    >
    >> int main(void)
    >> {
    >> printf("%.3lf\n",-2158470*0.001);
    >> }
    >>
    >> it prints
    >>
    >> -2158.470
    >>
    >> How can i disable '0' at the end, if they are not needed ?
    >>
    >> Is there a possibility just to write %lf and just print as many digits
    >> as needed to represent the number ?

    >
    > The l in %lf is superfluous, just use %f.

    Thank you for the info.
    > To avoid the trailing zeros try %g.


    I also tried %g:
    int main(void)
    {
    printf("%g\n",-2158475*0.001);
    }

    which results in
    -2158.47

    one digit is missed! this is a killing issue for me!

    how can i have the proper value displayed in all cases ?
    >
    > Jirka
     
    Guenther Sohler, Dec 20, 2005
    #5
  6. On Tue, 20 Dec 2005 12:08:23 +0000, usenet wrote:

    >
    > Guenther Sohle said:
    >>

    > (...)
    >> printf("%.3lf\n",-2158470*0.001);

    > (...)
    >> it prints
    >>
    >> -2158.470
    >>
    >> How can i disable '0' at the end, if they are not needed ? Is there a
    >> possibility just to write %lf and just print as many digits as needed to
    >> represent the number ?

    >
    > The problem is not in the printf() function, but in the way floating point
    > numbers are represented by your computer. Due to rounding errors, floating
    > point numbers hardly ever have the 'exact' value you would expect. Search
    > google for 'floating point' for some details, or read this wikipedia page:
    > http://en.wikipedia.org/wiki/Floating_point.
    >
    > It is up to you to make the choice how many digits are significant in a
    > number, so that is why you should tell printf() about this.


    I know, but the accuracy of double should still good enough to fulfill my
    purpose!
     
    Guenther Sohler, Dec 20, 2005
    #6
  7. On Tue, 20 Dec 2005 07:06:42 -0500, Chuck F. wrote:

    > Guenther Sohler wrote:
    > >
    >> I have following code:
    >>
    >> int main(void)
    >> {
    >> printf("%.3lf\n",-2158470*0.001);
    >> }
    >>
    >> it prints

    >
    > Your question, I believe, is "how to suppress trailing zeroes". A
    > little thought and an intermediary buffer should give you a
    > suitable answer for that.


    Thank you for the information. Yes, I also keep this in mind,
    but i use %f very often in my code ( > 100) and to suitable
    handle all them, I would have to write my own printf.
    I dont like to do this unless I am really sure there is no other way
     
    Guenther Sohler, Dec 20, 2005
    #7
  8. Guenther Sohler

    Jirka Klaue Guest

    Guenther Sohler:

    > I also tried %g:
    > int main(void)
    > {
    > printf("%g\n",-2158475*0.001);
    > }
    >
    > which results in
    > -2158.47
    >
    > one digit is missed! this is a killing issue for me!


    Well, then it's time for you to read the appropriate part
    of the standard.

    ISO/IEC 9899:TC2
    7.19.6.1#8
    g,G A double argument representing a floating-point number is converted
    in style f or e (or in style F or E in the case of a G conversion
    specifier), depending on the value converted and the precision.
    Let P equal the precision if nonzero, 6 if the precision is omitted,
    or 1 if the precision is zero. Then, if a conversion with style E
    would have an exponent of X:
    - if P > X ≥ -4, the conversion is with style f (or F) and
    precision P - (X + 1).
    - otherwise, the conversion is with style e (or E) and precision P - 1.
    Finally, unless the # flag is used, any trailing zeros are removed from
    the fractional portion of the result and the decimal-point character is
    removed if there is no fractional portion remaining.

    So try %.9g or something like that.

    > how can i have the proper value displayed in all cases ?


    This could be difficult depending on the meaning of proper.

    Jirka
     
    Jirka Klaue, Dec 20, 2005
    #8
  9. In article <> Guenther Sohler <> writes:
    ....
    > int main(void)
    > {
    > printf("%g\n",-2158475*0.001);
    > }
    >
    > which results in
    > -2158.47
    >
    > one digit is missed! this is a killing issue for me!
    >
    > how can i have the proper value displayed in all cases ?


    But, what *is* the proper value? In binary it is:
    -10000110110.01110011001100110011...
    and that is what is stored on the computer, most decimal numbers are
    not exactly representable in binary. So what will be stored is a
    rounded value, and the value in memory is:
    -2158.47499999999990905052982270717620849609375
    so what should the system do?

    --
    dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
    home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
     
    Dik T. Winter, Dec 20, 2005
    #9
  10. Guenther Sohler

    Old Wolf Guest

    Jirka Klaue wrote:

    > Guenther Sohler:
    >> Is there a possibility just to write %lf and just print as many digits
    >> as needed to represent the number ?

    >
    > The l in %lf is superfluous, just use %f.


    It is superfluous in C99, and is an error in C89. But most
    C89 compilers allow it anyway.
     
    Old Wolf, Dec 20, 2005
    #10
  11. Guenther Sohler

    Tatu Portin Guest

    Guenther Sohler wrote:

    > I have following code:
    >
    > int main(void)
    > {
    > printf("%.3lf\n",-2158470*0.001);
    > }
    >
    > it prints
    >
    > -2158.470
    >
    > How can i disable '0' at the end, if they are not needed ?
    >
    > Is there a possibility just to write %lf and just print as many
    > digits as needed to represent the number ?



    Question "How can I disable '0' at the end" indicates somekind of
    misconception of floating point numbers.

    Count of digits in a number indicates the accuracy of the number. So,
    if you just remove zero from a number, you decrease accuracy of the
    number.

    For example:
    -2158.5 could be result of rounding -2158.470, but it would be wrong
    to add zeros to -2158.5 because the accurate amount was -2158.470.

    The significance of zeros in indicating accuracy can be only perceived
    when handling numbers on right side of decimal point.
    For example:
    -2000 could be result of rounding -2158 or it could be the exact
    amount. You cannot tell if -2000 has one, two, three or four
    significant digits, i.e. if -2000 is accurate to first, second, third
    or fourth digit.
    This is why scientific notation is used to represent quantities.
    E.g. -2.000e3 is different from -2e3 in accuracy.


    --
    It's bit too late to be clear, but I hope I made my point through.

    C faq: http://www.eskimo.com/~scs/C-faq/top.html
    Reference: http://www.acm.uiuc.edu/webmonkeys/book/c_guide/
    Coding standards: http://www.psgd.org/paul/docs/cstyle/cstyle.htm
     
    Tatu Portin, Dec 21, 2005
    #11
  12. Guenther Sohler wrote:
    > ...
    > I know, but the accuracy of double should still good enough to fulfill my
    > purpose!
    > ...


    What exactly do you mean by "good enough" and "your purpose" in this case? Most
    of the time floating-point numbers that have innocent-looking decimal
    representations have infinitely long [periodic] representations in traditional
    binary positional notation. For example, both '0.001' and '2158.47' are such
    numbers. It is impossible to represent them precisely in 'double', which
    probably means that 'double's precision (or precision of any type of same
    structure, no matter how large) is definitely not "good enough" (assuming that I
    understood your "good enough" correctly).

    --
    Best regards,
    Andrey Tarasevich
     
    Andrey Tarasevich, Dec 21, 2005
    #12
  13. >> I know, but the accuracy of double should still good enough to fulfill my
    >> purpose!
    >> ...

    >
    >What exactly do you mean by "good enough" and "your purpose" in this case?

    (I'm not the original poster).

    It is difficult and very expensive to measure most any physical
    quantity to more significant digits than are present in a double.
    (15 in a typical IEEE float implementation). Exceptions may include
    currency and time.

    Gordon L. Burditt
     
    Gordon Burditt, Dec 21, 2005
    #13
  14. Guenther Sohler

    Simon Biber Guest

    Guenther Sohler wrote:
    > I have following code:
    >
    > int main(void)
    > {
    > printf("%.3lf\n",-2158470*0.001);
    > }
    >
    > it prints
    >
    > -2158.470
    >
    > How can i disable '0' at the end, if they are not needed ?
    >
    > Is there a possibility just to write %lf and just print as many digits
    > as needed to represent the number ?


    I can write a function to do it.

    #include <stdio.h>
    #include <string.h>

    char *sprintd(char *buf, size_t buf_size, double val, int precision)
    {
    /* write value into string */
    snprintf(buf, buf_size, "%.*f", precision, val);

    /* find decimal point */
    char *p = strchr(buf, '.'), *q;

    /* remove trailing zeros */
    if(p) for(q = strchr(p, 0) - 1; *q == '0'; --q) *q = 0;

    /* remove trailing decimal point */
    if(p && p[1] == 0) p[0] = 0;

    return buf;
    }

    int main(void)
    {
    char buf[100];
    printf("%s\n", sprintd(buf, sizeof buf, 355.0 / 113.0, 15));
    return 0;
    }

    --
    Simon.
     
    Simon Biber, Dec 21, 2005
    #14
  15. Guenther Sohler

    vishnu Guest

    write %.2lf inn place of %.3lf
     
    vishnu, Dec 21, 2005
    #15
  16. "vishnu" <> writes:
    > write %.2lf inn place of %.3lf


    What?

    Read <http://cfaj.freeshell.org/google/>.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Dec 21, 2005
    #16
  17. Guenther Sohler

    Joe Wright Guest

    Guenther Sohler wrote:
    > On Tue, 20 Dec 2005 12:08:23 +0000, usenet wrote:
    >
    >
    >>Guenther Sohle said:
    >>
    >>(...)
    >>
    >>> printf("%.3lf\n",-2158470*0.001);

    >>
    >>(...)
    >>
    >>>it prints
    >>>
    >>>-2158.470
    >>>
    >>>How can i disable '0' at the end, if they are not needed ? Is there a
    >>>possibility just to write %lf and just print as many digits as needed to
    >>>represent the number ?

    >>
    >>The problem is not in the printf() function, but in the way floating point
    >>numbers are represented by your computer. Due to rounding errors, floating
    >>point numbers hardly ever have the 'exact' value you would expect. Search
    >>google for 'floating point' for some details, or read this wikipedia page:
    >>http://en.wikipedia.org/wiki/Floating_point.
    >>
    >>It is up to you to make the choice how many digits are significant in a
    >>number, so that is why you should tell printf() about this.

    >
    >
    > I know, but the accuracy of double should still good enough to fulfill my
    > purpose!
    >
    >

    You are perhaps confusing accuracy and precision. A double will always
    be precise to 53 bits or 16 digits or whatever. Its value is often less
    accurate than that, depending on how it was contrived.

    --
    Joe Wright
    "Everything should be made as simple as possible, but not simpler."
    --- Albert Einstein ---
     
    Joe Wright, Dec 21, 2005
    #17
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. ben
    Replies:
    4
    Views:
    658
    Martin Ambuhl
    Jun 26, 2004
  2. David Mathog

    printf formats for size_t?

    David Mathog, May 12, 2005, in forum: C Programming
    Replies:
    6
    Views:
    4,984
    Clark S. Cox III
    May 13, 2005
  3. whatluo

    (void) printf vs printf

    whatluo, May 26, 2005, in forum: C Programming
    Replies:
    29
    Views:
    1,328
  4. Sanjay Kulkarni

    Trouble with formats in printf

    Sanjay Kulkarni, Mar 21, 2007, in forum: C Programming
    Replies:
    5
    Views:
    357
    Army1987
    Mar 21, 2007
  5. azza

    printf affects following printf/s

    azza, Oct 17, 2010, in forum: C Programming
    Replies:
    0
    Views:
    455
Loading...

Share This Page