Question:
I solve Olympiad problems of various kinds, when I worked in Pascal and never thought about the work of the "=" or "> =" operator in working with real numbers, I thought that there could be no problems with the accuracy of comparisons. But then I switched to C ++ and one teacher told me that "==" or "> =" cannot be used when working with real numbers in C, you need to write fabs(a - b) > eps
. And here's the question:
- Is it true?
- How to choose the right eps?
- And why could some tasks not pass all tests with such a feature, and when I wrote simply "==" they did.
Here's a concrete example. Problem after I changed LessEqual
to "<=". You are given a real number a and natural n. Find the nth root of a. The program should display a single number: the answer to the problem with an accuracy of at least 6 decimal places
#include <cstdio>
#include <iostream>
#include <cmath>
using namespace std;
const double eps = 1e-8;
const double eps2 = 1e-12;
bool Equal(double a, double b)
{
return fabs(a - b) < eps2;
}
bool lessEqual(double a, double b)
{
return ((a < b) || Equal(a, b));
}
double a;
int n;
void solve()
{
double l = 0,
r = a + 1,
mid = 0;
while (r - l > eps)
{
mid = (l + r) / 2;
if (lessEqual(pow(mid, n), a))
l = mid;
else
r = mid;
}
printf("%.7lf", l);
}
int main()
{
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
scanf("%lf\n", &a);
scanf("%d", &n);
solve();
return 0;
}
Answer:
The problem here is not in the "imprecise" comparison by the processor hardware, but in the fact that some decimal fractions cannot be accurately converted to binary floating point format.
Another problem is the loss of the least significant bits of the mantissa during calculations in loops.