1. Not finding help here? Sign up for a free 30min tutor trial with Chegg Tutors
    Dismiss Notice
Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

C program; trouble with doubles

  1. Jul 16, 2004 #1

    Math Is Hard

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    Hi - what do I need to do to take a double value as input and display it? Thanks.

    //This prints garbage:

    #include <stdio.h>
    int main(void)
    {
    double mydouble;

    printf("Enter a number\n");
    scanf("%f",&mydouble);
    printf("you typed %f\n", mydouble);

    return 0;
    }
     
  2. jcsd
  3. Jul 16, 2004 #2

    plover

    User Avatar
    Homework Helper

    scanf("%f",&mydouble);

    %f
    reads a float, for a double you want %lf

    However, %f works to print a double with printf.

    printf and scanf codes are often faux amis.
     
    Last edited: Jul 16, 2004
  4. Jul 16, 2004 #3

    AKG

    User Avatar
    Science Advisor
    Homework Helper

    If plover's idea doesn't help, use "%g" instead of "%f".
     
  5. Jul 16, 2004 #4

    Math Is Hard

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    plover and AKG - thanks so much for the suggestions. I am going to give this a try tonight.
    I had not heard of "%g". I better go look that up!
     
  6. Jul 16, 2004 #5

    plover

    User Avatar
    Homework Helper

    According to Harbison & Steele %f %g and %e should all act identically (and C99 adds %a). So:

    %f %g %e %a read a float
    %lf %lg %le %la read a double
    %Lf %Lg %Le %La read a long double
     
  7. Jul 16, 2004 #6

    AKG

    User Avatar
    Science Advisor
    Homework Helper

    Plover is right, ignore what I was saying. My book says %g is used to printf a double.
     
  8. Jul 16, 2004 #7

    Math Is Hard

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    using %lf with scanf()

    //This works better
    #include <stdio.h>
    int main(void)
    {
    double mydouble;

    printf("Enter a number\n");
    scanf("%lf",&mydouble);
    printf("you typed %f\n", mydouble);

    return 0;
    }
     
    Last edited: Jul 16, 2004
  9. Jul 16, 2004 #8

    Math Is Hard

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    using %lg with scanf()

    //This works pretty good too
    #include <stdio.h>
    int main(void)
    {
    double mydouble;

    printf("Enter a number\n");
    scanf("%lg",&mydouble);
    printf("you typed %g\n", mydouble);

    return 0;
    }
     
  10. Jul 16, 2004 #9

    Math Is Hard

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    Playing around with it, I entered the number 23.4567891 into each program.
    Without using any conversion mods,
    The first program with "%lf" returned 23.456789
    The second program with "%lg" returned 23.4568
    I am not exactly sure of the difference since I don't have any reference here.
     
  11. Jul 16, 2004 #10

    AKG

    User Avatar
    Science Advisor
    Homework Helper

    There are too many variables in your experiment. Try having two programs, one that scans with "%lf" and one with "%lg" but have them both print out with "%f." Then do the same where they both print out with "%g." Because, as you have it, it's hard to tell if it's the fact that you're scanning wiht "%lg" or printing with "%g" that's shrinking your output.
     
  12. Jul 16, 2004 #11

    Math Is Hard

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    you're absolutely right. I'll give that a try.
     
  13. Jul 16, 2004 #12

    plover

    User Avatar
    Homework Helper

    For printf (again from Harbison and Steele):
    %f or %lf prints a float or a double (use %Lf for long double) to a minimum precision
    %e or %le (respectively %Le) prints in scientific notation, again to a minimum precision
    %g or %lg (respectively %Lg) decides whether %f or %e fits the situation better, uses that, but then strips off trailing zeros

    %e %g use a lower case 'e' before the exponent, %E %G use upper case (%F is not a standard code).

    %a (%la %La %A etc) is a C99 addition for printing in hexadecimal floating point, but doesn't seem to be implemented in the libc I'm using (cygwin's).

    Try this:

    #include <stdio.h>
    int main(void)
    {
    double mydouble;

    printf("Enter a number\n");
    scanf("%lg",&mydouble);
    printf("you typed (%%f) %f\n", mydouble);
    printf("you typed (%%g) %g\n", mydouble);
    printf("you typed (%%e) %e\n", mydouble);

    return 0;
    }


    For more details on setting the precision and other formatting gewgaws, check out the floating point conversions page for glibc.
     
    Last edited: Jul 16, 2004
  14. Jul 16, 2004 #13

    plover

    User Avatar
    Homework Helper

    The default for %f is six digits after the decimal point. The default for %g is six significant figures. This explains the results for 23.4567891.

    Try these inputs: .000123456789 and .0000123456789
     
    Last edited: Jul 16, 2004
  15. Jul 17, 2004 #14

    Math Is Hard

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    This is going to be a pretty dumb question, but I am not very clear on what is meant by "significant figures". Can you help?

    oh, I tried your samples, plover. Thanks for that piece of code demostrating the different displays. %f displays 0.000123 and %g displays 0.0001234567
    This was very helpful! :smile:
     
  16. Jul 17, 2004 #15

    plover

    User Avatar
    Homework Helper

    Check the display for %g, it should be: 0.000123457 (no 6 - the 6 was rounded up). If it's not, something very strange is going on.

    Here's a tutorial on significant figures I found. If you don't like this one, googling turns up plenty more.

    Now that I think about it though, "significant figures" is not the correct term to describe what is going on. Apparently, the correct term in this case is "significant digits", which is the phrase that is actually used on the glibc page linked to above, and in my reference book. It had not registered with me earlier that there were two distinct terms here. However the description on the glibc page is a bit confusing.

    Here's my version of what's going on (in the default case):
    • Call the value to be converted v. If |v|>=10^7 or |v|<10^-3, use scientific notation, else use decimal notation.
    • If more than 6 digits remain to the right of any leading zeros, round the number so that 6 such digits remain.
    • Strip off trailing zeros if they are to the right of the decimal point.
    Thus:
    23.00 -> 23
    23.00001 -> 23
    2300.001 -> 2300
    23.67676 -> 23.6768
    0.001234566 -> .00123457


    You might also add the line:

    printf("you typed (%%#g) %#g\n", mydouble);

    to the program. The '#' causes trailing zeros not to be stripped.

    Here's a version of the program for playing with the "precision" specification. (And to puzzle over the notation... :wink: ) If you want to fiddle with this some more, you might try constructing the statements so that the "field width" can be set instead of (or in addition to) the "precision".

    #include <stdio.h>
    int main(void)
    {
    double mydouble;
    int precision;

    printf("Enter a number\n");
    scanf("%lg",&mydouble);
    printf("Enter a precision\n");
    scanf("%d",&precision);
    printf("\n");

    printf("With default precision:\n");
    printf(" %%f converts your number to: %f\n", mydouble);
    printf(" %%e converts your number to: %e\n", mydouble);
    printf(" %%g converts your number to: %g\n", mydouble);
    printf(" %%#g converts your number to: %#g\n", mydouble);
    printf("\n");

    printf("With precision %d:\n", precision);
    printf(" %%.%df converts your number to: %.*f\n", precision, precision, mydouble);
    printf(" %%.%de converts your number to: %.*e\n", precision, precision, mydouble);
    printf(" %%.%dg converts your number to: %.*g\n", precision, precision, mydouble);
    printf(" %%.%d#g converts your number to: %.*#g\n", precision, precision, mydouble);

    return 0;
    }
     
  17. Jul 17, 2004 #16

    Math Is Hard

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    plover, you are a wealth of information! Thanks so much!
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook

Have something to add?



Similar Discussions: C program; trouble with doubles
  1. C program: fopen() (Replies: 8)

  2. C program issues (Replies: 2)

  3. C++ Program Ideas (Replies: 9)

Loading...