Variable of type DOUBLE converts number strangely.

Discussion in 'C Programming' started by John, May 26, 2006.

  1. John

    John Guest

    I'm new to C and I know this is probably one of those "most commonly
    mis-interpreted as a problem", newcomer type of question, but for this code:


    double x;
    printf("Enter number:");
    scanf("%f", &x);
    printf("The number is %f", x);


    If I enter 2 as the number, the following is returned:
    -1.997517

    This doesn't happen for 'float', only for 'double'.

    Is there something I'm not getting here? Is there something I'm
    supposed to be doing?

    I'm teaching myself with GCC v3.3.6, and while I recall reading
    somewhere that floating point numbers do slightly different things, I
    didn't think they'd be THAT different!
     
    John, May 26, 2006
    #1
    1. Advertisements

  2. The difference is not where you think, but that the specifiers for scanf
    and not what they are for printf. When you supply printf with x an
    argument, the value of x is promoted to a double, whether x was a float
    or a double, so a single specifier ("%f") works for both. But scanf
    gets the address of that x supplied as a argument. When x is a float,
    &x is the address of a float; when x is a double, &x is the address of a
    double. Those are different things, which possibly different sizes and
    possibly different internal forms, so need different specifiers. See
    code below:

    #include <stdio.h>

    int main(void)
    {
    double x;
    char input_string[] = "2";

    /* similar to your posted code */
    printf("Enter number:");
    fflush(stdout);
    #if 0
    scanf("%f", &x); /* replaced so not dependent on
    keyboard typing */
    #endif
    sscanf(input_string, "%f", &x); /* gcc should give a diagnostic if
    you invoke it with reasonable
    options. */
    printf("%s\n", input_string); /* to look like you typed it */
    printf("The number is %f\n\n", x);

    /* notice the change in the sscanf specifier below */
    printf("Enter number:");
    fflush(stdout);
    sscanf(input_string, "%lf", &x);
    printf("%s\n", input_string);
    printf("The number is %f\n", x);

    return 0;
    }
     
    Martin Ambuhl, May 26, 2006
    #2
    1. Advertisements

  3. John

    pete Guest

    scanf and printf are not symetric on %f.
    %f prints a double.
    %f scanfs a float.
    %lf scanfs a double.
     
    pete, May 26, 2006
    #3
  4. John

    John Guest


    Ah, so I see. There is a different data type identifier I should use to
    scanf a double, "%lf", which I guess stands for "long float"? The book
    I'm studying didn't get to that and all previous examples so far have
    been "%f".

    Anyway, when I add that to my scanf, everything works fine now. THanks!
     
    John, May 26, 2006
    #4
  5. To expand on that:

    %f prints a double, but in effect it can print either a float or a
    double (because a float is impicitly promoted to double).

    No such promotion can occur for scanf, which expects a pointer to a
    float or double *object*, not just a float or double *value*.
     
    Keith Thompson, May 27, 2006
    #5
  6. gcc with -Wall catches this easily.
     
    Frodo Baggins, May 27, 2006
    #6
  7. gcc with -Wall catches this easily.

    HTH
    Regards,
    Frodo Baggins
     
    Frodo Baggins, May 27, 2006
    #7
    1. Advertisements

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.