### rodz's blog

By rodz, 5 years ago,

Consider the following C++ code:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
double f(ll x,ll y,ll p,ll q)
{
double n = ((1.0 * p) * (1.0*y)) / (1.0*q) - x;
double d = (1.0 - (1.0*p)/(1.0*q));
return n/d;
}
int main()
{
ll x = 1, y = 2, p = 499999999 , q = 500000000;
cout << fixed << setprecision(6);
cout << f(x, y, p, q) << endl;
cin >> x >> y >> p >> q;
cout << f(x, y, p, q) << endl;
return 0;
}


When I run it on Custom Invocation with input 1 2 499999999 500000000 it prints two different values. I know floating point calculations may have precision issues but why does it make a difference whether I read the input from stdin or hardcode it into the variables?

• +11

 » 5 years ago, # |   +3 Maybe, it is because when computing the answer, you divide over d. And d is almost 0, so n / d is inf or nan? Or better said, undefined behavior. Then, the results could be different.
•  » » 5 years ago, # ^ | ← Rev. 2 →   0 In this case, d = 2e-9. It's a small value, but isn't NaN or inf. I don't know if it is small enough to cause undefined behavior. But yes, undefined behavior is the best explanation I have so far. I wanted to know if anyone here has a better / more detailed explanation.
 » 5 years ago, # | ← Rev. 2 →   +36 In this particular case, optimizer is probably the one playing tricks. Add #pragma GCC optimize("O0") on the top of your code (somewhat equivalent to -O0 in command line) and see if behavior now becomes same for both invocations. For example, optimizer may: Inline f. Reorder calculations differently in two different cases. Pre-calculate the first value printed. Again, in different order. Use double (64-bit) in some places and FPU registers (80-bit) in other places, which will cause different precisions. If you want to dig deeper, I suggest you look at optimized tree or assembly code generated.I believe there are also a plenty of other reasons. I can't stress this enough: never rely on floating point computations! Re-ordering and "obvious optimizations" may and will change calculation error.
•  » » 5 years ago, # ^ |   +10 Great answer! It seems you are correct. Thank you. Will try harder to avoid using floating points.