Solved

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

Posted on 2008-11-06
335 Views
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);

}
``````
0
Question by:Noo2this

LVL 24

Expert Comment

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

LVL 45

Expert Comment

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

Author Comment

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

LVL 45

Accepted Solution

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

## Featured Post

Recently while returning home from work my wife (another .NET developer) was murmuring something. On further poking she said that she has been assigned a task where she has to serialize and deserialize objects and she is afraid of serialization. Wha…
In my previous two articles we discussed Binary Serialization (http://www.experts-exchange.com/A_4362.html) and XML Serialization (http://www.experts-exchange.com/A_4425.html). In this article we will try to know more about SOAP (Simple Object Acces…
The goal of this video is to provide viewers with basic examples to understand opening and reading files in the C programming language.
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.