22

Teaching myself C and finding that when I do an equation for a temp conversion it won't work unless I change the fraction to a decimal. ie,

tempC=(.555*(tempF-32)) will work but tempC=((5/9)*(tempF-32)) won't work.

Why?
According to the book "C Primer Plus" it should work as I'm using floats for both tempC and tempF.

Chef Flambe
  • 885
  • 2
  • 15
  • 35
  • Does this answer your question? [What is the behavior of integer division?](https://stackoverflow.com/questions/3602827/what-is-the-behavior-of-integer-division) – cigien Feb 27 '22 at 16:32

5 Answers5

19

It looks like you have integer division in the second case:

tempC=((5/9)*(tempF-32))

The 5 / 9 will get truncated to zero.

To fix that, you need to make one of them a floating-point type:

tempC=((5./9.)*(tempF-32))
Mysticial
  • 464,885
  • 45
  • 335
  • 332
  • 5
    To be picky, the 5.0 / 9.0 syntax gives two doubles. If tempF and tempC are `float` then the expression should be 5.0f / 9.0f. Otherwise the division might be performed on double precision, which is then rounded to float precision when its result is stored. Hopefully the compiler is smart enough to optimize that minor little issue away, but I wouldn't count on it. – Lundin Jan 18 '12 at 12:53
  • @Lundin it can't optimize that out; if double precision is used, it must be done that way, or an unexpected answer may arise. – rubenvb Jul 16 '13 at 14:40
3

When you do 5/9, 5 and 9 are both integers and integer division happens. The result of integer division is an integer and it is the quotient of the two operands. So, the quotient in case of 5/9 is 0 and since you multiply by 0, tempC comes out to be 0. In order to not have integer division, atleast one of the two operands must be float.

E.g. if you use 5.0/9 or 5/9.0 or 5.0/9.0, it will work as expected.

COD3BOY
  • 11,964
  • 1
  • 38
  • 56
Divya
  • 2,594
  • 1
  • 17
  • 29
3

5/9 is an integer division not a floating point division. That's why you are getting wrong result.

Make 5 or 9 floating point variable and you will get correct answer.

Like 5.0/9 OR 5/9.0

  • Agreed. It is always good practice to also add the `f` denoting floating point to constants. Likewise the `u` for unsigned integer constants – Andrew Oct 27 '12 at 20:32
1

5/9 is an integer expression, as such it gets truncated to 0. your compiler should warn you about this, else you should look into enabling warnings.

Necrolis
  • 25,836
  • 3
  • 63
  • 101
  • 3
    I really don't see why it should warn. There is no way for the compiler to tell what value someone wants their integer constants to be. – Lundin Jan 18 '12 at 07:59
  • 1
    @Lundin: thats why it would be a (pedantic) warning. if a constant integer expression yields zero, it should either be zero or there was an oversight. – Necrolis Jan 18 '12 at 08:31
  • Not necessarily, there may be many cases where you would want a constant expression with the result 0. For example `result = SOME_CONSTANT & MASK;` may very well result in zero. Lets say you have similar bit masking operations all over the code, with different masks. You wouldn't want hundreds of warnings then, why should you be punished just because you write generic, consistent code without any magic numbers in it? – Lundin Jan 18 '12 at 12:45
  • @Lundin: but thats not a division, I'm *only* referring to division here. – Necrolis Jan 18 '12 at 13:22
  • `SOME_CONSTANT / SOMETHING` isn't really any different from my example. Lets say that the constant states the number of outputs this build of the program is using, and the division is used to calculate the nature of the output. – Lundin Jan 18 '12 at 15:08
0

If you put 5/9 in parenthesis, this will be calculated first, and since those are two integers, it will be done by integer division and the result will be 0, before the rest of the expression is evaluated.

You can rearrange your expression so that the conversion to float occurs first:

tempC=((5/9)*(tempF-32));tempC=(5*(tempF-32))/9;

or of course, as the others say, use floating point constants.

Mr Lister
  • 45,515
  • 15
  • 108
  • 150
  • Even if they were not in parenthesis, they could still be evaluated as integers. The order of evaluation of this expression is unspecified behavior in C, the compiler may chose to evaluate left-to-right or right-to-left, and you cannot know which order of evaluation that applies. – Lundin Jan 18 '12 at 07:57
  • 1
    Not entirely true. The parenthesis do have an effect! If you make sure that the first calculation that is performed results in a float, the rest of the expression will not revert back to integer. I've augmented my answer to show what I mean. – Mr Lister Jan 18 '12 at 08:33
  • The rewritten example is not equivalent to removing the parenthesis, you have intentionally changed the order of evaluation. `tempC= 5/9 * (tempF-32);` is an example with the parenthesis removed. This example may or may not give the desired result, depending on whether the compiler evaluates left-to-right or right-to-left - it relies on unspecified behavior. – Lundin Jan 18 '12 at 12:02
  • 1
    I'm not sure what you're trying to prove here. My example rewrote the OP's expression so that it works. Which is what they asked for. – Mr Lister Jan 18 '12 at 13:07