# Thread: I can't figure out why my code is rounding to a wrong number.

1. ## I can't figure out why my code is rounding to a wrong number.

I am doing practice problem for an online course and I copied a code from my class. This is a program for converting fahrenheit to celsius. They spoke about saving fahrenheit and celsius as an integer on purpose to illustrate how the program will round.

Code:
```#include <stdio.h>
int main(void)
{
int fahrenheit, celsius;

printf("Please enter fahrenheit as an integer:");
scanf("%d", &fahrenheit);
celsius = (fahrenheit - 32)/1.8;  //Why is this converting to 99?
printf("\n%d fahrenheit is %d celsius.\n", fahrenheit, celsius);
return 0;
}```
For some reason when I enter 212 as the Fahrenheit, I get 99 as an answer in Celsius. I thought because I divided celsius by 1.8 it should do the conversion as a double but then get rounded back to an integer when saved in celsius. I keep getting 99 as an answer. If I do the math, it should be (212-32)=180 then 180/1.8=100 Sorry for the newbie question but I am confused as this was supposed to be a lesson on how things get rounded when you use different data types. I am new to coding and don't understand what is happening. 2. Floating point is not a precise thing.

1.8 is not representable as an accurate floating point number, so what you really have is 1.80000000001 or something.
That tiny extra is enough to make your '100' result to be 99.99999999

However, taking the integer part of that truncates it down to 99.

Use the integer equivalent of
(fahrenheit - 32) * 5 / 9; 3. ## Code:
`celsius = (float)( (fahrenheit - 32) / 1.8 ) ;`
C - Type Casting - Tutorialspoint 4. The cast won't help if the underflow has already happened. 5. Originally Posted by Structure Code:
`celsius = (float)( (fahrenheit - 32) / 1.8 ) ;`
C - Type Casting - Tutorialspoint
That might actually make the problem worse. The expression ( (fahrenheit - 32) / 1.8 ) is already of type double, and casting it to float reduces its precision before the value is then converted to int. 6. Here's a brief explanation about 'floating point' based on Salem's correct comments on the subject above.

"Precision" is the number of significative digits (in this case, BITS) of a representation. 'double' has 53 bits of precision, 'float', 24... And, yes, 'int' has 31 bits of precision in 32 or 64 bits systems (usually). Floating point is a estruture to store RATIONAL values (a fraction A/B, where B is fixed). Any floating point (following IEEE 754 standard -- which is, today, de facto, standard) encodes a fractional "normalized" value using the formula:

v=(-1)^S * ( 1 + F/(2^(P-1)) ) * 2^(E-bias)

Where S, F and E are POSITIVE integer values... using 'double precision', P=53, so F has 52 bits, E has 11 bits and S, only 1.

The value 1.8 is encoded as:

1.8 approx (-1)^0*(1 + 3602879701896397/4503599627370496)*2^(1023-1023). Here S=0, F=3602879701896397 and E=1023. This gives us 1.800000000000000044408920985006261616945266723632 8125. Notice if the value 3602879701896396 for F, the final value would be 1.799999999999999822364316059974953532218933105468 75, which is off by a greater error...

So, 'floating point' is ALWAYS an approximation based on a fraction of 2 integers.

As Salem explained, if you divide 180 by this representation of 1.8, you'll get:

Code:
```\$ bc
scale=50
180/((-1)^0*(1 + 3602879701896397/(2^52))*2^(1023-1023))
99.99999999999999753283772305520774881638218981451873```
When truncated to `int` will give you 99, not 100.

My advice: Avoid using floating point at all costs!

PS: How did I got those values? This way:

Code:
```#include <stdio.h>

// ieee-754 double precision structure.
struct dbl_s
{
unsigned long long f: 52;
unsigned long long e: 11;
unsigned long long s: 1;
} __attribute__ ( ( packed ) );

int main ( void )
{
double d = 1.8;
struct dbl_s *p = ( struct dbl_s * ) &d;

printf ( "%.52f = (-1)^%u*(1 + %llu/%llu)*2^(%u-1023)\n",
d,
( unsigned int ) p->s,
( unsigned long long ) p->f,
1ULL << 52,
( unsigned int ) p->e );
}``` Popular pages Recent additions celsius, celsius;, enter, fahrenheit, int 