2

F = (C * 9/5 ) + 32 and F = (9/5 * C) + 32 yield two different results although the input for C is the same. I realize that there is some kind of precedence in operators but i am not sure about it. Does multiplication come before division ?

An input of 20 gives the Fahrenheit value as 68(correct one) in the first case and 52 in the second.

#include<stdio.h>

int main()
{
    float cel , fahr ; 
    printf("Enter the temperature(C): ");
    scanf("%f",&cel);
    fahr = (9/5 * celt is  ) + 32;
    printf("\nThe temperature in fahranheit is %f ",fahr);

}

Expected result is 68 but its 52 for the above code. If I switch the position of '9/5' and 'cel' it gives the correct result. Why is that ?

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Geo Mukkath
  • 145
  • 11

4 Answers4

7

Multiplication and division have equal precedence in C, and left-to-right associativity. So,

  • F = (C * 9/5 ) + 32 is equivalent to F = ((C * 9)/5) + 32
  • F = (9/5 * C) + 32 is equivalent to F = ((9/5) * C) + 32

The two expressions would be algebraically equivalent, except for the fact that C defines int / int = int, discarding the remainder. So, 9/5 is not 1.8 as you might have expected, but 1.

To get a floating-point result from dividing two ints, you need to convert at least one of the operands to float or double. So instead of 9/5, write:

  • 9.0/5.0, 9.0/5, 9/5.0, or 1.8, which gives you a double, or
  • 9.0f/5.0f, 9.0f/5, 9/5.0f, or 1.8f, which gives you a float
dan04
  • 87,747
  • 23
  • 163
  • 198
  • 1
    So `F = ((C * 9)/5) + 32` will be more precise than `F = ((9/5) * C) + 32` – Paul Ogilvie Aug 20 '19 at 16:04
  • no, the expression: `9/5` results in 1 due to integer truncation of the fraction – user3629249 Aug 20 '19 at 20:13
  • 2
    IMHO the best is to use all floating point, as the problem is talking about temperatures: `F = 9.0/5.0 * C + 32.0;` When converting temperatures it is better to think as a scientist, not as an assembler programmer :) OMG! this program is the second example of K&R book!!! Doesn't anybody read it? – Luis Colorado Aug 21 '19 at 07:17
4

Yes, precedence (and integer arithmetic).

They're evaluated like this:

F = ((C * 9)/5 ) + 32;

vs.

F = ((9/5) * C) + 32;

The way C does integer arithmetic (it truncates integers towards zero) makes the second incorrect (9/5 is one).

Instead, use 9.f, 5.f, and 32.f. That way, precedence won't change much (and you'll get correct results).

S.S. Anne
  • 15,171
  • 8
  • 38
  • 76
3

Besides the precedence problem, the result of 9/5 is 1. It would work more like expected if it were written

9.0/5       or
9/5.0        or
9.0/5.0       or (even)
1.8
wallyk
  • 56,922
  • 16
  • 83
  • 148
  • 3
    Don't forget the `f` suffix. The OP is dealing with `float`s. – S.S. Anne Aug 20 '19 at 15:35
  • 5
    @JL2210: the explicit type suffix `f` is not needed except for the pickiest of compilers. The expression will be evaluated as a `double` and truncated to a `float` on assignment to `fahr`. – wallyk Aug 20 '19 at 15:37
  • 1
    Yes, but in general, try to avoid implicit type changes (they surprise you when you're not paying attention). – S.S. Anne Aug 20 '19 at 16:04
  • 2
    @JL2210 Implicit type conversions are a *feature of the language*. Avoiding them is silly; doing so denies the utility of using a higher-order language in the first place. Naturally you have to learn to avoid a few pitfalls (this question demonstrates a dandy one), but I have to disagree with your blanket advice to "avoid implicit type changes". In general they're fine. – Steve Summit Aug 20 '19 at 16:29
  • implicit type conversions can (and often will) result in values other than what the programmer is expecting. That is why the compiler (when warnings are enabled) outputs a warning message about the problem – user3629249 Aug 20 '19 at 20:15
3

This expression

C * 9/5

is evaluated form left to right because the used operators have the same precedence.

So, it is evaluated like

( C * 9 ) / 5

Each time when a sub-expression is evaluated the compiler determines the common type of the used operands.

The common type of the sub-expression

C * 9

is float according to the usual arithmetic conversions. So the result of this sub-expression has the type float and the result of the whole expression

( C * 9 ) / 5

is correspondingly has the type float.

This expression

9/5 * C

is evaluated like

(9/5) * C

As the both operands of the sub-expression

9/5

are integers then there is used the integer arithmetic and the result of the sub-expression is also integer.

To avoid the dependence of the order of operands you could for example write

(9.f/5) * C

or

(9/5.0f) * C

In this case the sub-expressions

8.0f/5

and

8/5.0f

are evaluated as an expression with float numbers.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • why everybody insists in using integers, when all the arithmetic mus be done in floats? With this approach, the newcomers to C will believe that using floating point literals is an expensive task. Nothing further from reality. – Luis Colorado Aug 21 '19 at 07:20