0

Why in C, when I print a double type variable with %f it shows 8.000000… but that is not the desire result . i want a result like 8.5000 how can i achieve this?

 int main(){
     int i, j;
      double k;
      i=8; j=9;
      k = (i+j)/2;
      printf("%f", k);
    }
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
sam
  • 853
  • 3
  • 19
  • 50

3 Answers3

1

The problem is not with the format specifier, rather with the arithmatic operation.

By saying

 k = (i+j)/2;

where, i and j and 2 - all are ints, you're doing integer division, and then, storing the result in a double. For integer division,

[..] When integers are divided, the result of the / operator is the algebraic quotient with any fractional part discarded [...]

which is commonly known as "truncation towards zero". To avoid that from happenning, you need to enforce floating point arithmetic, by forcing or casting one of the operands to double (or float). Something like

k = ((double)i+j)/2;

or,

k = (i+j)/2.0;  //2.0 is of type double 

The point here is, if, in the operation, one of the operands is of the higher rank (double or float is higher ranked that int), all the operands will first be converted to the higher rank, and then the operation will be performed and the result will be of the type of the higher ranked type.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
0

Since i and j are int the result is cast first to int. This looses precision. Explicitly cast to double k = (double)(i+j)/2

Bpaul
  • 87
  • 6
  • 1
    I would say the result is an integer right away as only integer arithmetic will be performed. There is no cast involved at that point. – GermanNerd Nov 15 '18 at 12:50
0

Comments are right. To better understand that: A C expression is evaluated in 'one chunk'. The right side of your assignment (i+j)/2 is a complete expression. Since it does only includes integer values, the arithmetic chosen will also be of integer type, (which leads to truncation of the result), creating temporary integer value (invisible to you), which is then assigned to a double.

You need to make at least one of the values in your expression a double (or float), then the compiler will promote all the arithmetic to floating point and the temporary value will also be of float type.

If you don't have a constant in your expression, you can also use casts:

((float)i+J)/2

It does not matter which of the 3 items get the cast, just one is enough.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
GermanNerd
  • 643
  • 5
  • 12
  • `creating temporary integer value (invisible to you), which is then assigned to a double ---> truncation.` is that so? – Sourav Ghosh Nov 15 '18 at 12:19
  • @Sourav Ghosh AFAIK yes. – GermanNerd Nov 15 '18 at 12:21
  • 1
    I dont think so. If you try to mean that the result of integer division tends to truncate the result - I agree. But storing an integer in a double results in truncation - can you cite some source of that? – Sourav Ghosh Nov 15 '18 at 12:23
  • Well, if I look at a disassembly, the arithmetic is performed using integer addition and right shift. The assigment into the double is preceded by cvtsi2sd (conversion from int to float) on an x86-64 processor. So, yes I'd say the intermediate value, which is kept in a gp-register, is indeed a temporary integer. The truncation already happens when the arithmetic is performed. – GermanNerd Nov 15 '18 at 12:39
  • 1
    Ah, I see our misunderstanding. Bad wording on my side, sorry. I'll edit my answer. – GermanNerd Nov 15 '18 at 12:41
  • No problem, we're here to help each other to rule out the confusions and increase the overall quality, cheers!! – Sourav Ghosh Nov 15 '18 at 13:07