PDA

View Full Version : C expressions always evaluating to 0? Why?


singularity2006
02-06-2004, 07:26 AM
I'm writing a temperature conversion program in C but I keep having this funky problem where scanf works fine and it records my initial temperature fine, but when it gets run through the expression to convert it to degrees F, it always evaluates to 0. Any ideas? Here's the code:


int celcius(void)
{

//local variables
float degC = get_celcius();
float degF = celcius_to_fahrenheit(degC);

//statements
print_fahrenheit(degF);
return 0;

}

float get_celcius(void)
{

//local variables
float degC;

//statements
printf("Please enter a temperature value in degrees Celcius: ");
scanf("%f", &degC);
return degC;

}

float celcius_to_fahrenheit(float degC)
{

//statements
return degC * 1.8 + 32;

}

int print_fahrenheit(float degF)
{

//statements
printf("Your temperature converts to %.2f degrees Fahrenheit\n", degF);
return 0;

}

iC4
02-06-2004, 09:04 AM
just tested your code, works fine for me.

stew
02-06-2004, 12:39 PM
return degC * 1.8 + 32;
make that
return degC * 1.8 + 32.0;
If you do float calculations in C, make sure all variables and constants involved are floats.

singularity2006
02-06-2004, 04:51 PM
Originally posted by iC4-
just tested your code, works fine for me.

you know, I think my compiler has gone bad. Using Visual C++ from MS Viz Studio 6 and the compiler totally crapped out on my laptop. Gave me weird critical compile errors and such. However, using bloodshed's DevC++ worked grrreeeeaaat! It actually worked.

What the heck can kill the compiler? I noticed the compiler on my desktop is doing the same thing though but isn't giving me anything critical. Just evaluating freakishly weird things after compiling normally.

Can anyone recommend any other good compilers?

singularity2006
02-06-2004, 04:54 PM
Originally posted by stew
return degC * 1.8 + 32;
make that
return degC * 1.8 + 32.0;
If you do float calculations in C, make sure all variables and constants involved are floats.

thanks for the info. I was under the assumption that int values are converted to floats or larger depending on the largest data type in the expression. So would it be totally necessary to write 32 as 32.0?

schmu_20mol
02-06-2004, 05:44 PM
Originally posted by singularity2006
Can anyone recommend any other good compilers?

This is a list of (good) c++ compilers many of them support c too. (ok bash me around if all of them do :banghead:

compiler list (http://www.research.att.com/~bs/compilers.html)

I personally use gcc and i like it - it's a free one and normally installed with about every linux distro ... so simply take it if you work on linux ... for some critical/important projects i'll perhaps go on and evaluate most of them to find the one that fits my needs better for the situation ... but for normal things gcc is more than just fine ... well enough blah ... good luck

playmesumch00ns
02-06-2004, 06:38 PM
Originally posted by singularity2006
thanks for the info. I was under the assumption that int values are converted to floats or larger depending on the largest data type in the expression. So would it be totally necessary to write 32 as 32.0?

Nope, unfortunately not. Always make sure to cast int variables to floats if you want to get a float result from a calculation

singularity2006
02-06-2004, 08:53 PM
that's pretty fascinating. So in the least, shouldn't I get an answer that is an int? I find it weird that it would give me just a flat 0.

StefanDidak
02-06-2004, 09:42 PM
Originally posted by singularity2006
that's pretty fascinating. So in the least, shouldn't I get an answer that is an int? I find it weird that it would give me just a flat 0.

Imagine having half a dozen small bugs like that in a substantial application. :)

What you've been running into is that the compiler you're using doesn't support implicit casting (and thus requires explicit casting instead). Often a compiler will do implicit casting in the optimizer (so you may want to try yours again with some different optimization switches on or try out some different warning levels). Other than that it's compiler-dependent and while most support float-double and int-enum, etc. implicit casts they usually do not support it for float-int). It's best to stick to a coding convention that dictates explicit casting because it makes your code a bit easier to maintain... especially when hunting for vague casting mayhem.

singularity2006
02-06-2004, 11:43 PM
it's still not working... very lost. HEre's the complete code. I even tried: (float)degF = (float)degC * (float)1.8 + (float)32 ... it still assigns 0 to degF.... what is going on??



//libraries
#include <stdio.h>

//prototype definitions: layer 2
int celcius();

//prototype definitions: layer 3 part 1
float get_celcius();
float celcius_to_fahrenheit();
int print_fahrenheit();

//prototype definitions: layer 3 part 2

//global definitions
float degC;
float degF;

int main(void)
{
printf("======================================================================");
printf("\nTEMPERATURE CONVERSION UTILITY v1.0\n");
printf("This application will convert user defined temperatures in degrees\n");
printf("Celcius and Fahrenheit and convert them to degrees Fahrenheit and\n");
printf("Celcius, respectively.\n");
printf("======================================================================\n\n");
celcius();
return 0;
}

int celcius(void)
{
degC=get_celcius();
degF=celcius_to_fahrenheit(degC);
print_fahrenheit(degF);
return 0;
}

float get_celcius(void)
{
float degC;
printf("Please input a temperature value in degrees Celcius: ");
scanf("%f", &degC);
return degC;
}

float celcius_to_fahrenheit(degC)
{
float degF;
degF = degC * 1.8 + 32.0;
printf("%.2f", degF);
return degF;
}

int print_fahrenheit(degF)
{
printf("Your temperature converts to %.2f degrees Fahrenheit\n", degF);
return 0;
}

StefanDidak
02-07-2004, 12:09 AM
Originally posted by singularity2006
it's still not working... very lost. HEre's the complete code. I even tried: (float)degF = (float)degC * (float)1.8 + (float)32 ... it still assigns 0 to degF.... what is going on??


For starters your code is hard to read even though it's only a few lines. You are re-using variables names in the functions that you have already defined as global (and are thus confusing and in a large project would be extremely confusing). Also, you define prototypes of functions but you omit the function spec (the parameters). These should at least look like:

float celcius_to_fahrenheit(float);
int print_fahrenheit(float);

I am surprised your compiler allows you to even compile that without throwing you errors or warnings.

The functions celcius_to_fahrenheit and print_fahrenheit have a rather odd construct in using the global variable definition as a parameter spec. Again, your compiler should have thrown a fit over something like that. Try writing them like:

float celcius_to_fahrenheit(float value)
int print_fahrenheit(float value)

...and make sure you replace the reference to 'value' as well of course or else it won't work and you'll have structural problems.

But what surprises me most of all is that your compiler isn't warning you that the "degF = value * 1.8 + 32.0;" is a conversion from double to float and thus could result in a precision loss. Try writing them as floats like this:

degF = value * 1.8F + 32.0F;

That should take care of the conversion which your compiler seems to be having a problem with.

I'm not sure what to say but I would suggest using a different compiler because the one you are using must be a piece of... (fill in the blank). :)

But seriously... if you are going to learn programming and I see these kinds of problems you are running into, which clearly should have been caught by the compiler at some level, then I have to strongly suggest using a compiler that at least does a decent job because right now your compiler is causing you these frustrations.

The abbreviated version below runs just fine. Try putting it through your compiler and see what it does.


#include <stdio.h>

int main(int argc, char* argv[])
{
float degC;
float degF;

printf("Please input a temperature value in degrees Celcius: ");
scanf("%f", &degC);
degF = degC * 1.8F + 32.0F;
printf("\nConverts to %.2f degrees Fahrenheit\n", degF);
return 0;
}

singularity2006
02-07-2004, 04:53 AM
much thanks for the tips. Based on what I could figure out from the teacher, I could omit the spec if the variables were global. Anyhow, I have undone that and renamed variables and such and here is what I have .... btw, the 1.8F and 32.0F gives me errors. It gives me an undeclared identifier error for F. I think that's for C++, not C. I'm programming in C.

Anyhow, first time I ran that code, I got a HUGE number output. Now it returns only 0 again.


//libraries
#include <stdio.h>

//prototype definitions: layer 2
float celcius();

//prototype definitions: layer 3 part 1
float get_celcius();
float celcius_to_fahrenheit();
int print_fahrenheit();

//prototype definitions: layer 3 part 2


int main(void)
{
printf("======================================================================");
printf("\nTEMPERATURE CONVERSION UTILITY v1.0\n");
printf("This application will convert user defined temperatures in degrees\n");
printf("Celcius and Fahrenheit and convert them to degrees Fahrenheit and\n");
printf("Celcius, respectively.\n");
printf("======================================================================\n\n");
celcius();
return 0;
}

float celcius(void)
{

//local definitions
float degC_input;
float degF_output;

//statements
degC_input=get_celcius();
degF_output=celcius_to_fahrenheit(degC_input);
print_fahrenheit(degF_output);
return 0;

}

float get_celcius(void)
{

//local definitions
float degC_input;

//statements
printf("Please input a temperature value in degrees C: ");
scanf("%f", &degC_input);
return degC_input;

}

float celcius_to_fahrenheit(float degC_input)
{

//local definitions
float degF_output;

//statements
degF_output = degC_input * (float)1.8 + (float)32.0;
return degF_output;

}

int print_fahrenheit(float degF_output)
{

//statements
printf("Your temperature converts to %.2f degrees Fahrenheit\n\n", degF_output);
return 0;

}

singularity2006
02-07-2004, 05:36 AM
i figured it out. Declared my prototypes incorrectly.

I had originally:

//prototype declarations
float celcius_to_fahrenheit();

I had to change it to:

float celcius_to_fahrenheit(float degC_input);

I totally missed that point... man, I miss Visual Basic...
:cry:

playmesumch00ns
02-07-2004, 09:35 AM
Yeah can't believe I missed that one too! Was just about to post when I saw you'd done it....

don't worry, you won't miss visual basic for long.

StefanDidak
02-07-2004, 10:56 AM
Originally posted by singularity2006
btw, the 1.8F and 32.0F gives me errors. It gives me an undeclared identifier error for F. I think that's for C++, not C. I'm programming in C.

The suffix is a vanilla ANSI C standard but if it's (old style) C you may want to change the F to f instead (capitalized suffix was introduced later). Still, the proto param spec should've been caught by your compiler regardless.

singularity2006
02-07-2004, 10:08 PM
Much thanks Stefan! :beer:

Anyhow, I have a trashy compiler. It compiled without any parameter spec just fine. Stupid MS VC++..... Anyhow, I like the compiler for DevC++ but the only drawback is that the program doesn't hold the program long enough for me to get a screen shot. At least MS Viz Studio pauses the screen so I can see what the final output is. With that said, is there another method other than stickinging in a while(1) statement to hold the screen?

StefanDidak
02-07-2004, 10:15 PM
Originally posted by singularity2006
With that said, is there another method other than stickinging in a while(1) statement to hold the screen?

I'm not sure what you mean by holding the screen but I assume you are not running the final executable from the commandline? That would keep the console open whereas most IDE's that call upon a console will often close it after execution completes.

schmu_20mol
02-07-2004, 10:46 PM
Originally posted by singularity2006
With that said, is there another method other than stickinging in a while(1) statement to hold the screen?

that would be the equivalent of


std::cin.get()


in C++ ...
it basically waits for any key to be pressed ... hope I understood what you where looking for

...if you're running it directly in the command line as Stefan suggested there's no need for that

iC4
02-08-2004, 11:58 AM
since he is using c, I would suggest getch() from the <stdio>

singularity2006
02-08-2004, 06:04 PM
hhmmm... we haven't learned about getch() yet though. And yes, running from command line is something I should be doing but I'm too used to just running the executable from the Windows shell, which instantly closes as soon as it is run instead of keeping the DOS window open.

iC4
02-08-2004, 08:08 PM
just include <stdio.h> and put getch(); at the end in your main function.

singularity2006
02-08-2004, 08:23 PM
very cool, I'll give that a go, thanks. :thumbsup:

CGTalk Moderation
01-17-2006, 09:00 AM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.