# C++. Celsius to Fahren. conver; What temp R they = ?

1. Jun 23, 2014

### burton95

I must write a program that finds the temperature, as an integer, that is the same in both Celsius and Fahrenheit. The formula for this is

F=(9/5)C+32

The program should create two integer variables for the temperature in Celsius and Fahrenheit. Initialize the temperature to 100 degrees Celsius. In a loop, decrement the Celsius value and compute the corresponding temperature in Fahrenheit until the values are the same.

my code
Code (Text):

#include <iostream>
using namespace std;

int main()
{
int c_temp = 100;
int f_temp = 212;

while (c_temp != f_temp)
{
f_temp = ((9 * c_temp) / 5) + 32;
c_temp--;
}
cout << "The temperature when they are both the same is: " << c_temp << endl;
}

Answer is - 40 but I keep getting -43. What am I missing? I tried changing int to doubles and then it wouldn't run. Thanks

Anthony

Last edited by a moderator: Jun 23, 2014
2. Jun 23, 2014

### cpscdave

I only see 1 problem but it doesn't explain your result.

Code (Text):
cout << "c_temp: " << c_temp << " vs f_temp: " << f_temp << endl;
That will allow you to see what the code believes is happening.

Also note cause you decrements c_temp, then do the check at the start of the loop if you immediately output c_temp it will be 1 less than the correct result.
what I mean is
c_temp is -40
f_temp is calc'd to be -40
c_temp is decremented to -41
while loop condition fails
output c_temp as -41

3. Jun 23, 2014

### burton95

thanks cpscdave, I added your print line code and obviously it doesn't stop @ -40. I don't get it.

c_temp: -34 vs f_temp: -29
c_temp: -35 vs f_temp: -31
c_temp: -36 vs f_temp: -32
c_temp: -37 vs f_temp: -34
c_temp: -38 vs f_temp: -36
c_temp: -39 vs f_temp: -38
c_temp: -40 vs f_temp: -40
c_temp: -41 vs f_temp: -41
c_temp: -42 vs f_temp: -43
The temperature when they are both the same is: -43

4. Jun 23, 2014

### burton95

Oh and berkman asked if I could add code tags. Its he referencing code tags in the body of the post or as a tag for the post?

5. Jun 23, 2014

### D H

Staff Emeritus
Your problem is you aren't following directions. The problem says to do the following:
In a loop, decrement the Celsius value and compute the corresponding temperature in Fahrenheit until the values are the same.​
You aren't doing that. Here's what you are doing:
In a loop, compute the corresponding temperature in Fahrenheit and decrement the Celsius value until the values are the same.​

A lesser problem: You aren't computing the correct values at times. For example, -36 C and -32.8 F are the same temperature. Your program reports a value of -32 F. It would be better to report a value of -33 F as the integral value of that -32.8 F value.

6. Jun 23, 2014

### burton95

Thanks DH. It says to use int's so that is what I'm doing. Seems pretty obvious now.

7. Jun 23, 2014

### cpscdave

OHHHHHH I know why your loop isn't working now :)

A couple things. Berkman means in the body of the post, like how I posted the cout code.

I don't want to tell you exactly why your loop isn't working. There is good learning in figuring it out on your own. But I'll give you a hint. The issue you are having is similar to the output problem I referenced early.
Ask yourself if the cout is saying that c_temp and f_temp are equal (when they both are -40) why isn't the loop exiting and why when they aren't equal (-42 vs -43) does the loop exit :)

8. Jun 23, 2014

### D H

Staff Emeritus
That's why I wrote that second and also added that this is a lesser problem.

Did you read the first part of my post?

Does that mean you have solved the problem?

9. Jun 23, 2014

### burton95

The return value is correct, -40. I have a feeling getting loops to run the correct amount of times is going to be tricky topic for me for a while. Thanks to both of you.

10. Jun 23, 2014

### cpscdave

So you figured it out??

Start and stop conditions for loops is something that can be tricky at time.

For loops the way I do things generally is:
If I know how many times exactly a loop needs to be ran: For loop
If the loop needs to run AT least 1 or more times: do while loop
If the loop needs to run 0 or more times: while loop

This problem would've fallen into the do while category the way you set it up :)

11. Jun 23, 2014

### D H

Staff Emeritus
You need to take care. Errors similar to yours pop up all the time. Suppose you need to make a linear fence 100 meters long using 10 meter long sections of fencing. How many fenceposts do you need? (The answer is 11, not 10.) A similar error: You have 10 fenceposts. How many sections of fencing do you need to build a linear fence using all your fenceposts? (The answer is 9, not 10.) Thinking the answer to these questions is ten occurs so frequently that these mistakes are called fencepost errors.

These two kinds of fencepost errors are in the larger class of off-by-one errors. Yours is essentially an off-by-one error. You need to watch out for them.

12. Jun 23, 2014

### D H

Staff Emeritus
Integers between -224 and 224 are be stored exactly in a single precision IEEE floating point number. For double precision numbers, integers between -253 and 253 are be stored exactly.

A value of -40 will be stored exactly, and the floating point computation (9.0*40)/5.0 + 32.0 will be exactly 40.0.

13. Jun 24, 2014

### FactChecker

The calculation is only an integer every 5'th iteration. My comment was just to warn about testing for equality of floats to terminate the loop. It is pure luck that the solution of x=9x/5+32 is an integer.

Last edited: Jun 24, 2014
14. Jun 24, 2014

### AlephZero

When x = -40, or any fairly small multiple of 5, it is not "pure luck", if your computer uses IEEE arithmetic.

Some non-IEEE hardware did give nasty surprises over this. In particular the early Cray supercomputers didn't have any special-purpose hardware for division, but calculated a/b as a*reciprocal(b), where "reciprocal" was calculated by a software function, using an iterative algorithm. A reciprocal like 1/5 can NOT be represented exactly as a binary value, so a/5 was never an exact value, unless a = 0.

In general the warning about testing equality of floats is valid, of course.

15. Jun 24, 2014

### FactChecker

I thought the same thing till a couple of weeks ago, when someone on another post gave this example:
Code (Text):

Perl code:
$x = 25.4 / 10.0 * 1.0 / 2.54 ;$y = (25.4 / 10.0) * (1.0 / 2.54);
printf ("%g %s %g\n", $x, (($x == $y) ? "=" : "!="),$y);

I ran it on a Wintel PC and got: "1 != 1"
So IEEE 754 does not guarantee as much as I thought it did.

16. Jun 24, 2014

### D H

Staff Emeritus
That was my example.

Nonetheless, AlephZero is correct. (9.0*x)/5.0 is exact when x is a "small" multiple of 5, where "small" means |x|≤9007199254740990. There's no problem here since 40 is much less than 9007199254740990.

Compare to (9.0/5.0)*x. That's where luck might kick in. Lesson to be learned: Watch how you arrange your expressions. The math you learned in school doesn't quite apply to floating point formats such as IEEE 754. Floating point arithmetic isn't commutative or associative. One might think that (9.0*x)/5.0 and (9.0/5.0)*x should yield the same result, but they oftentimes don't.

This is all a bit off-topic since the OP was specifically told to use integers. There's no problem with an exact comparison for integers.

17. Jun 24, 2014

### FactChecker

I am curious about how you can identify the problem calculations like your example versus others like this that are not a problem.
The OP mentioned that a version using floating point calculations did not run. He didn't say exactly what that code was. I suspect that it did not terminate because he was decrementing C in the wrong place and the solution was not at the integral C values of his loop.

18. Jun 24, 2014

### FactChecker

One bit of "pure luck" is that the solution of the equation x = 9x/5 + 32 is an integer value exactly divisible by 5 and that the sequence of integer calculations with intermediate truncations gives the correct value.

Regarding the "pure luck" of testing equality of two floating point calculations, I do not know how to distinguish a calculation that gives a false (-40 != -40) result from one that gives a correct result (-40 == -40) result where the two sides are calculated differently.

Last edited: Jun 24, 2014
19. Jun 25, 2014

### D H

Staff Emeritus
A short list, by no means complete.
• Know what an inexact result is, and know what causes them. 9.0/5.0 is inexact. 40.0/5.0 is not (it's exact).

• Know how rounding works. Consider the following:
Code (Text):
int rintx  = std::lrint (x);
int roundx = std::lround (x);
int floorx = std::floor (x + 0.5);
int ceilx  = std::ceil (x - 0.5);
int intx   = int(x + std::copysign(0.5, x));
What's the difference between the above five rounding schemes?

• Know what ULP means.

• Know all the ways in which a calculation can suffer massive loss of precision.