10

Consider following code:

#include <iostream>

using namespace std;

int aaa(int a) {
    cout << a * 0.3 << endl;
    return a * 0.3;
}

int main()
{
    cout << aaa(35000);
}

It prints out:

10500
10499

Why output differs?

I have a workaround to use "return a * 3 / 10;" but I don't like it.

Edit:

Found that doing "return float(a * 0.3);" gives expected value;

user2534633
  • 945
  • 1
  • 8
  • 11
  • 1
    `cout << a * 0.3` use type double as the result. but in second output you pass the result from int type filter. – Emadpres Jun 29 '13 at 13:08

3 Answers3

9

The result of 0.3*35000 is a floating point number, just slightly less than 10500. When printed it is rounded to 10500, but when coerced into an int the fractional digits are discarded, resulting in 10499.

Joni
  • 108,737
  • 14
  • 143
  • 193
  • Is it not compiler specific? gcc prints 10500 in both cases – banarun Jul 03 '13 at 07:50
  • 2
    It is. In fact 10500 can be represented *exactly* as a floating point number, and if the multiplication is made with 64 bits the result should be 10500 *always*. The thing is, some systems use 80-bit precision for intermediate values. This makes 0.3 slightly less than 3/10, and when the result of the multiplication is rounded it is wrong in the last bit. – Joni Jul 03 '13 at 08:43
6

int * double expression yields double, that's what the first thing prints. Then you convert to int chopping the remaining part (even if it's almost there, sitting at 10500-DBL_EPSILON), and pass that back. The second prints that value.

float-int conversions should be made with care, better not at all.

doctorlove
  • 18,872
  • 2
  • 46
  • 62
Balog Pal
  • 16,195
  • 2
  • 23
  • 37
2

a * 0.3 has type double. The call inside aaa calls

ostream& operator<< (double val);

whereas the one outside calls

ostream& operator<< (int val);

You'd get a warning (if you turn them on - I suggest you do) that the implicit cast from double to int isn't recommended.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625