This question already has answers here:
C++ program converts fahrenheit to celsius
(8 answers)
Closed 4 years ago.
So I am using an Atmega328p and a MCP9808 to take some i2c temp values. Im running it to my computer and viewing it in termial via USART.
Im getting the correct values for Celsius degrees (it shows 00022, which is around 71 degrees which is correct for my room).
However when I try to convert to fahrenheit I get values of 00054 which is def. not correct.
This is the formula im using:
float fahrenheitConvert(uint16_t celsius) {
float fahrenheit;
fahrenheit = celsius*(9/5) + 32;
return fahrenheit;
}
celsius is simply a uint16_t value called "Temperature" in the main program (Which is what is printed out through serial just fine). Am I missing something? This seems like it should be a simple conversion?
9/5 is performed as truncating integer math, and evaluates to 1 (because 9/5 discarding fractional components is 1). So your calculation is simplifying to:
fahrenheit = celsius * (1) + 32;
or just:
fahrenheit = celsius + 32;
which is obviously unhelpful.
To fix, change one of the literals to a double literal so the math naturally converts to double math:
fahrenheit = celsius * 9 / 5.0 + 32;
Now you use integer math to compute celsius * 9, then implicitly coerce to double when you divide by 5.0, keeping the decimal component of the calculation.
Side-note: You don't actually need to separate this code into a declaration, an assignment, and a return. The body of this function could simplify to just:
return celsius * 9 / 5.0 + 32;
and it would work equally well.
Related
This question already has answers here:
Integer division returns 0 in C
(2 answers)
Closed last year.
I wanted to get the convert from Fahrenheit to Celsius with this program, but it always returns 0. Why?
#include <stdio.h>
int main() {
int fahr = 15, celsius;
celsius = (5 / 9) * (fahr - 32);
printf("%d\n", celsius);
return 0;
}
It seems that the problem is in celsius = (5 / 9) * (fahr - 32);. I already know that celsius = 5 * (fahr - 32) / 9; fixes the problem. But why did the first one return zero?
In short, when performing arithmetic operations, C compiler has to choose which number format to use. To do this, it won't pick the one of the first operand, nor try to guess what the result would be, but will opt for the most precise type of both operand.
In your particular example, (5 / 9) use two integers, so the result will remain an integer too, thus zero.
A quick way to fix this is to directly specify a decimal in your constant :
(5 / 9.0)
The other answers and comments are steering you in the correct direction with regards to integer division vs floating point. But if you want to avoid floating point altogether and still produce a correct answer (as an integer), then structure your equation such that division comes last.
Since (x/y) * z is the same as (x * z)/y, then this holds:
celsius = (5 * (fahr - 32)) / 9;
In C, if you do a division between two integer type variables, you get an integer back.
So this:
(5 / 9)
gets a result of 0.555, which is then rounded down. (In C, integer division rounds towards zero.)
If you changed it like this, it would be floating point division instead:
celsius = (5.0 / 9) * (fahr - 32);
I need some help with a program for converting Fahrenheit to Celsius in C. My code looks like this
#include <stdio.h>
int main(void)
{
int fahrenheit;
double celsius;
printf("Enter the temperature in degrees fahrenheit:\n\n\n\n");
scanf("%d", &fahrenheit);
celsius = (5 / 9) * (fahrenheit - 32);
printf("The converted temperature is %lf\n", celsius);
return 0;
}
Every time I execute it it the result is 0.000000. I know I'm missing something but can't figure out what.
5/9 will result in integer division, which will = 0
Try 5.0/9.0 instead.
You problem is here :
celsius = (5/9) * (fahrenheit-32);
5/9 will always give you 0. Use (5.0/9.0) instead.
try celsius = ((double)5/9) * (fahrenheit-32); Or you can use 5.0.
The fact is that "/" looks at the operand type. In case of int the result is also an int, so you have 0. When 5 is treated as double, then the division will be executed correctly.
write 5/9.0 instead of 5/9 -- this forces double division
You need to use floating point arithmetic in order to perform these type of formulas with any accuracy. You can always convert the final result back to an integer, if needed.
When dealing with floats, it needs to be 5.0f / 9.0f.
When dealing with doubles, it needs to be 5.0 / 9.0.
When dealing with integers, remainders/fractions are always truncated. 5 / 9 results between 0 and 1, so it is truncated to just 0 every time. That multiplies the other side by zero and completely nullifies your answer every time.
int main (void)
{
int fahrenheit; // fahrenheit stands for fahrenheit
double c; // c stands for celsius
printf("Enter your fahrenheit, we'll covnvert it into celsius! ");
scanf("%f", &fahrenheit);
c = 5/9 * (fahrenheit - 32);
printf("Here is your %f in celsius!.\n");
return (0);
}
I've followed the code through break points and when it takes in my input the calculations are off, but the formula is correct. Some sort of logic error I can't put my finger on. Please help!
The scanf call uses the wrong format string. You are reading an int so you need it to be:
scanf("%d", &fahrenheit);
The expression 5/9 is evaluated using integer division. In fact the compiler can work it out at compile time. That expression evaluates to 0.
You need to perform floating point division. For instance:
5.0/9
Or:
5/9.0
Or
5.0/9.0
You just need at least one operand to be a floating point value.
Putting this into your expression, you can write:
c = 5.0/9.0 * (fahrenheit - 32);
and obtain the answer that you expect.
Your printf statement is wrong too. You should enable warnings and let the compiler tell you that. You meant to write:
printf("Here is your %f in celsius!.\n", c);
Integer math versus floating point math.
i = 5/9 // i is equal to 0
d = 5.0/9.0 // d is equal to whatever 5 divided by 9 would actually be
You also need to actually print the value:
printf("Here is your %f in celsius!.\n", c);
Short answer: Operations on integers return integers even if the variable you store the result on is a double. Divisions between integers are truncated.
You should write this instead:
c = 5.0/9.0 * (fahrenheit - 32.0);
Adding a ".0" (or even just a ".") to your constant makes them floating point values.
This question already has answers here:
Why does dividing two int not yield the right value when assigned to double?
(10 answers)
Why does division result in zero instead of a decimal?
(5 answers)
Closed 9 years ago.
When writing a program in C to convert celsius to fahrenheit, the following formula gives the incorrect output:
int fahr = 9 / 5 * celsius + 32;
Now, I understand that this is probably an issue with 9/5 being interpreted as an integer, but what I don't understand is that using double or floatit still gives the same incorrect output.
Oddly enough the following formula gives the correct output despite also setting the type to int:
int fahr = celsius / 5 * 9 + 32;
Furthermore, i've noticed even something as simple as the below, when the type is set to double, still gives the output as 1.0 instead of 1.8:
double x = 9 / 5;
printf("%lf\n", x);
I've read this thread:
C program to convert Fahrenheit to Celsius
but I still don't understand why int fahr = celsius / 5 * 9 + 32; works but not int fahr = 9/5 * celsius+32; ?
You're doing math with integers. This expression:
9 / 5
Yields 1 in C. When you say you used double or float, you probably just changed the type of fahr, which doesn't do anything to the operations taking place on the right side of the assignemtn operator. To get the right behaviour, you need to make at least one of those constants a double, too:
9.0 / 5
Likewise, in this statement:
double x = 9 / 5;
You're still doing integer math, and then assigning the result to a double variable. There isn't anything else going on. You'll get the right answer by doing one of these:
double x = 9.0 / 5;
double x = 9 / 5.0;
double x = 9.0 / 5.0;
The reason this expression:
int fahr = celsius / 5 * 9 + 32;
appears to work is just an order of operations thing - here you divide the input by 5 and then multiply by nine, rather than doing the constant operation first. You'd still get more accurate answers by doing:
int fahr = celsius * 9 / 5 + 32;
Besides that, you could also do floating point math in this expression:
int fahr = celsius * 9.0 / 5 + 32;
If you want to do the original calculation using integers, you certainly can - you just need to multiply before dividing:
int fahr = 9 * celsius / 5 + 32;
This expression is equivalent to one of the ones used above.
I still don't understand why int fahr = celsius / 5 * 9 + 32; works but not int fahr = 9/5 * celsius+32;
For the former, you probably declared celsius as a float or as a double, making the entire right side evaluate as such. Assuming you used float, it works out like this:
celsius / 5 * 9 + 32
(celsius / 5.0) * 9 + 32
(celsius / 5.0 * 9.0) + 32
(celsius / 5.0 * 9.0 + 32.0)
For the latter, 9/5 is integer arithmetic that evaluates to 1 before the rest of the math happens as floating point. In this case:
9 / 5 * celsius + 32
1 * celsius + 32 // Because of this, you get an incorrect answer
celsius + 32
celsius + 32.0
Note the the type of the left hand side is irrelevant; the right-hand side is evaluated without regard to that.
Update: You said celsius is an int, which means you just happened to get lucky and test with a value that is a multiple of 5, giving you a correct integer result to celsius / 5 before doing valid integer arithmetic for the rest of the statement. In your second example, being a multiple of 5 doesn't help you.
In any case, now you know why you got lucky, but the linked question gives you the answer to what you actually need to to do have a formula that works when celsius isn't a multiple of 5: use floating point math, as demonstrated in all of the answers there.
The type of each expression or subexpression is (in most cases) evaluated without regard to the context in which it appears.
In this declaration:
double x = 9 / 5;
the initialization expression is 9 / 5; it consists of two int expressions and a division operator. Since the operands of / are of type int it's an int division, resulting in an int value. Since integer division truncates, the result is 1, of type int.
The result of that expression is then used to initialize x. Since x is of type double, the value is implicitly converted from int to double, resulting in x holding the value 1.0.
If you want the value of x to be 1.8, you need to do floating-point division, which means you need floating-point operands. The simplest and clearest way to do this is:
double x = 9.0 / 5.0;
There are several other (IMHO less clear) approaches. If a / operator has two operands, one of type int and one of type double, the int operand is promoted to double, so either of these will also set x to 1.8:
double x = 9.0 / 5;
/* or */
double x = 9 / 5.0;
But be careful with this approach:
double y = 9 / 5 / 3.0;
This is equivalent to:
double y = (9 / 5) / 3.0;
which computes 9 / 5 as an int, yielding 1, then promotes that result to double and divides it by 3.0, yielding 0.333333333.
The point is that the context of an expression does not impose a type on the expression or its operands; the expression is evaluated as if it were isolated, and then the result may be converted depending on its context.
I need some help with a program for converting Fahrenheit to Celsius in C. My code looks like this
#include <stdio.h>
int main(void)
{
int fahrenheit;
double celsius;
printf("Enter the temperature in degrees fahrenheit:\n\n\n\n");
scanf("%d", &fahrenheit);
celsius = (5 / 9) * (fahrenheit - 32);
printf("The converted temperature is %lf\n", celsius);
return 0;
}
Every time I execute it it the result is 0.000000. I know I'm missing something but can't figure out what.
5/9 will result in integer division, which will = 0
Try 5.0/9.0 instead.
You problem is here :
celsius = (5/9) * (fahrenheit-32);
5/9 will always give you 0. Use (5.0/9.0) instead.
try celsius = ((double)5/9) * (fahrenheit-32); Or you can use 5.0.
The fact is that "/" looks at the operand type. In case of int the result is also an int, so you have 0. When 5 is treated as double, then the division will be executed correctly.
write 5/9.0 instead of 5/9 -- this forces double division
You need to use floating point arithmetic in order to perform these type of formulas with any accuracy. You can always convert the final result back to an integer, if needed.
When dealing with floats, it needs to be 5.0f / 9.0f.
When dealing with doubles, it needs to be 5.0 / 9.0.
When dealing with integers, remainders/fractions are always truncated. 5 / 9 results between 0 and 1, so it is truncated to just 0 every time. That multiplies the other side by zero and completely nullifies your answer every time.