Connecting Tech Pros Worldwide Forums | Help | Site Map

Variable of type DOUBLE converts number strangely.

John
Guest
 
Posts: n/a
#1: May 26 '06
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!

Martin Ambuhl
Guest
 
Posts: n/a
#2: May 26 '06

re: Variable of type DOUBLE converts number strangely.


John wrote:[color=blue]
> 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![/color]

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;
}




pete
Guest
 
Posts: n/a
#3: May 26 '06

re: Variable of type DOUBLE converts number strangely.


John wrote:[color=blue]
>
> 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'.[/color]

scanf and printf are not symetric on %f.
%f prints a double.
%f scanfs a float.
%lf scanfs a double.

--
pete
John
Guest
 
Posts: n/a
#4: May 26 '06

re: Variable of type DOUBLE converts number strangely.


Martin Ambuhl wrote:[color=blue]
> John wrote:
>[color=green]
>> 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![/color]
>
>
> 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;
> }
>
>
>
>[/color]


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!
Keith Thompson
Guest
 
Posts: n/a
#5: May 27 '06

re: Variable of type DOUBLE converts number strangely.


pete <pfiland@mindspring.com> writes:
[...][color=blue]
> scanf and printf are not symetric on %f.
> %f prints a double.
> %f scanfs a float.
> %lf scanfs a double.[/color]

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 (The_Other_Keith) kst-u@mib.org <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.
Frodo Baggins
Guest
 
Posts: n/a
#6: May 27 '06

re: Variable of type DOUBLE converts number strangely.


Martin Ambuhl wrote:[color=blue]
> John wrote:[color=green]
> > 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[/color][/color]

[color=blue][color=green]
> > I'm teaching myself with GCC v3.3.6>[/color][/color]
[color=blue]
> The difference is not where you think, but that the specifiers for scanf
> and not what they are for printf.[/color]

gcc with -Wall catches this easily.

Frodo Baggins
Guest
 
Posts: n/a
#7: May 27 '06

re: Variable of type DOUBLE converts number strangely.


Martin Ambuhl wrote:[color=blue]
> John wrote:[color=green]
> > 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[/color][/color]

[color=blue][color=green]
> > I'm teaching myself with GCC v3.3.6>[/color][/color]
[color=blue]
> The difference is not where you think, but that the specifiers for scanf
> and not what they are for printf.[/color]

gcc with -Wall catches this easily.

HTH
Regards,
Frodo Baggins

Closed Thread