Why does the number after a decimal point turn to zero in C?

Noo2this
Noo2this used Ask the Experts™
on
In C, I use the below code to display a number (with decimal points) that registers on a Richter scale.  When I type 5.3, the return value displays 5.0.  I always thought that you should use type double (%f)when dealing with decimal points but that didn't work.  Someone suggested using float and that seems to somewhat help but it always returns a "0" after the decimal point regardless of what number is input.  Can anyone tell me why?
#include <stdio.h>
int
main(void)
{
       float n=0;       /* represents number registered */
        printf("Type the number registered on the Richter scale and press return> ");
      	// scanf(" %1f", &n);
		scanf(" %1f", &n);
		printf("You entered : %.1f\n", n);
		 
if (n < 5.0)
        printf("%f causes little or no damage.\n", n);
else if (n >= 5 && n < 5.5)
        printf("%f rating causes some damage.\n", n);
else if (n >= 5.5 && n < 6.5)
        printf("%f rating does serious damage: walls may crack or fall.\n", n);
else if (n >= 6.5 && n < 7.5)
        printf("%f disastrous results: houses and buildings may collapse.\n", n);
else
        printf("%f Catastrophic: most buildings are destroyed.\n", n);
return (0);
}

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
fridomCEO/Programmer

Commented:
The  problem is the format for scanf. It's 1f that's not what you want you want
%f or possible %g or %lf

it's an l not a 1

With just the change to use %f do I get:
./a.out                  
Type the number registered on the Richter scale and press return> 5.2
You entered : 5.20
5.200000 rating causes some damage.


Regards
Friedrich
Hi Noo2this,

If you want to trim the value to 1 decimal place, you can do it mathematically, or just limit the display to 1 decimal place with the format string;

  float f;
  int   i;

  scanf ("%f", &f);
  n = f * 10;
  f = (float)n / 10;

Or simpler is to do as you've done and just print one decimal place.   :)


As long as this is a learning exercise, you can simplify the logic in your block of *if* statements.  The first *if* handles all conditions when the value is less than 5.  The second *if* handles all conditions where the value is between 5 and 5.5.  Because the first *if* statement already tested for the value being less than 5, it's not necessary to test it again.  You can write that same block more simply as:

if (n < 5.0)
        printf("%f causes little or no damage.\n", n);
else if (n < 5.5)
        printf("%f rating causes some damage.\n", n);
else if (n < 6.5)
        printf("%f rating does serious damage: walls may crack or fall.\n", n);
else if (n < 7.5)
        printf("%f disastrous results: houses and buildings may collapse.\n", n);
else
        printf("%f Catastrophic: most buildings are destroyed.\n", n);



Good Luck,
Kent

Author

Commented:
Fridom, I tried using the "%If" and that did not work.  I did change the scanf back to "%f" but it still gave me a whole bunch of numbers and not the proper result.  Perhaps its the MS Visual Studio 2005 program that I'm using.  Thanks for the response.
Kdo, I guess I'm not ready for that mathematical portion just yet but I did simplify the logic like you said and that made a lot of sense.  I also altered my code a little:
float n;
printf("Type the number registered on the Richter scale and press return> ");
scanf("%f", &n);
printf("You entered : %.1f\n", n);

if (n < 5.0)
printf("%.1f causes little or no damage.\n", n);  etc., etc.
By changing the "%f" into "%.1f", I was able to get the result I was looking for.
Why does "float n;" work instead of "double n;" and what are your thoughts on switch statements for resolving this problem?
Hi Noo2this,

The browser's font sometimes makes certain characters tough to see.  :(  

Note Fridom's suggestion to try "%lf" -- that's a lower case 'L' in the middle.  Not an 'I' and not a '1'.  That may not solve your problem, but it should map correctly to a double.  It may be that your compiler builds the parameter list by inserting a double, not a float.  If you change *n* to be a double instead of a float, you'll definitely want to make this change to the format statement, too.

Switch isn't applicable here.  It requires an integer value and you want to evaluate the fractional part of a float.

A *switch* statement can be incredibly efficient.  When possible, it's usually better to use a *switch* statement than repeated *if* statements.  As the number of *case* items increases *switch* gets even better, especially when the *case* values are clustered.

The compiler tries to build a jump-table out of the values that it encounters in the *switch* statement.  This entity allows an almost identical execution time (of two jump instructions) no matter which *case* element is matched.  By using repeated *if* statements, performance can vary depending on how many of the *if* statements have to be evaluated.


Good Luck,
Kent

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial