с плавающей запятой — оператор C ++ == не работает

я применяю метод Регула Фальси в C ++, но проблема с оператором ==, когда F (x3) становится 0, то if (fabs (f (x3)) == 0 должен остановиться и выходит из цикла, но это не останавливает, почему, почему, почему ….
аналогично выводу ниже после 12-й итерации f (x3) = 0, но if (fabs (f (x3) == 0)) не запускается. цикл не останавливается, он не должен идти к 13-й итерации

float f(float x)
{

float  f_x;
f_x= pow(x,3)+(3*x)-5;
return f_x;
}
int main(int argc, char** argv)
{

float  a,b,tol,x3;

int itr,n;

cout << "enter the iterations";
cin >> itr;
cout << "enter the interval a";
cin >> a;
cout <<"enter the interval b";
cin >> b;
cout << "enter the toleration";
cin >> tol;

cout.setf(std::ios_base::fixed, std::ios_base::floatfield);
cout.precision(5);

//cout<<"fa="<<f(a)<<"fb"<<f(b);
cout<<"n\t\ta\t\tb\t\tx3\t\tf(a)\t\tf(b)\t\tf(x3)" <<endl;
if (f(a)*f(b)<0 && a<b)
{
for (n=0;n<itr;n++)
{
x3=a-((b-a)*f(a))/(f(b)-f(a));
cout << "xx"<<fabs(f(x3));

if (fabs( f(x3))==0)
{
cout << "Solution"<<fabs(f(x3));
break;
}
else
{
cout<<n+1 <<"\t\t"<<a <<"\t\t"<<b <<"\t\t"<<x3<<"\t\t"<<f(a)
<<"\t"<<f(b)<<"\t\t"<<f(x3) <<endl;
if(f(x3)*f(a)<0)
b=x3;
else
if(f(x3)*f(b)<0)
a=x3;
}
}
}
else
cout<< "No Solution Exist";

return 0;

}

ВЫХОД

введите итерации13

введите интервал a1

введите интервал b2

введите допуск1

**n   a          b             x3          f(a)           f(b)          f(x3)**1  1.00000    2.00000        1.10000     -1.00000        9.00000      -0.36900

2  1.10000    2.00000        1.13545     -0.36900        9.00000      -0.12980

3  1.13545    2.00000        1.14774     -0.12980        9.00000      -0.04487

4  1.14774    2.00000        1.15197     -0.04487        9.00000      -0.01542

5  1.15197    2.00000        1.15342     -0.01542        9.00000      -0.00529

6  1.15342    2.00000        1.15391     -0.00529        9.00000      -0.00181

7  1.15391    2.00000        1.15408     -0.00181        9.00000      -0.00062

8  1.15408    2.00000        1.15414     -0.00062        9.00000      -0.00021

9  1.15414    2.00000        1.15416     -0.00021        9.00000      -0.00007

10 1.15416    2.00000         1.15417    -0.00007        9.00000      -0.00003

11 1.15417    2.00000         1.15417    -0.00003        9.00000      -0.00001

12 1.15417    2.00000         1.15417    -0.00001        9.00000       0.00000

13 1.15417    2.00000         1.15417    -0.00000        9.00000       0.00000

0

Решение

Проблема здесь не точность с плавающей точкой; это терпимость, которую вы готовы принять в своем результате. В большинстве случаев regula falsi будет приближать вас к правильному результату по мере того, как вы будете проходить больше итераций, но это не дать вам точный ответ. Итак, решение, которое вы должны принять, заключается в том, насколько близко вы хотите, чтобы результат был? Это компромисс между реальными требованиями к точности и временем, необходимым для получения результата; Большая точность требует больше вычислительного времени. Поэтому выберите допуск, приемлемый для вашей задачи, и повторяйте цикл, пока результат не окажется в пределах этого допуска. Если он окажется слишком медленным, вам придется увеличить допуск.

1

Другие решения

Арифметика с плавающей точкой имеет ошибки точности, поэтому в большинстве случаев лучше не сравнивать значения с плавающей запятой напрямую, используйте эпсилон:

bool float_equal(float a , float b)
{
return std::abs(a-b) < 0.001;
}

Обратите внимание, что в вашем случае (сравнение с нулем) точность важнее: реализации с плавающей точкой не используются, чтобы обеспечить большую точность около нуля. Таким образом, вы можете иметь, например, числа типа 0,000000000001 или 0,0000000000000000001, которые не считаются равными нулю.

Проверьте эту тему для большего количества соображений: Какой самый эффективный способ сравнения с плавающей запятой и двойного сравнения?

Кроме того, обратите внимание, что станд :: setprecision является манипулятором, который изменяет точность операций вывода (печати), а не точность «системы» с плавающей точкой.

3

Вы уверены, что f (x3) равно 0, а не, скажем, 0.0000000001?

Числа с плавающей точкой могут быть очень точными около 0, иногда даже до 45 цифр после точки.

2
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector