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

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

Noo2thisAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

fridomCEO/ProgrammerCommented:
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
0
Kent OlsenData Warehouse Architect / DBACommented:
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
0
Noo2thisAuthor 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?
0
Kent OlsenData Warehouse Architect / DBACommented:
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
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
.NET Programming

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.