Redukcja cyfr znaczących w równaniu kwadratowym,błąd względny.

0

Witam serdecznie!
Czy ktoś mógłby pomóc mi z zadaniem? Zadanie ma wyliczać błąd względny pomiaru w procentach miedzy pierwiastkami wprowadzonymi ,a tymi ,które będą wyliczane ze wzoru. (Czyli np wprowadzamy jako pierwiastki 1e10 oraz 1e-10 i ze "wzoru szkolnego" po obliczeniach dostajemy 1e10 oraz -0 gołym okiem widać różnicę .Jak ją wykazać procentowo ,jeżeli odejmowanie nie działa?)
Podajemy pierwiastki równania na wejściu ,po czym wyliczamy a,b,c równania ze wzoru viete'a ,z czego wyliczamy normalnie deltę i pierwiastki.
Problem pojawia przy bardzo dużych cyfrach zmiennoprzecinkowych wyniki diametralnie zaczynają się różnić od siebie ,to nic dziwnego ,ale kiedy próbuję porównać ich sumę komputer nie widzi różnicy chodź widoczna jest ona gołym okiem,wiem że wiąże się ona z problemem utraty cyfr znaczących. Wiem ,że nie powinno się przyrównywać ze sobą dwóch podobnych wyników o tym typie ,ale jak temu zaradzić,jak inaczej do tego podejść ?
Jak wyliczyć tą różnicę pomiędzy pierwiastkami. Z góry dziękuję za pomoc

Oto mój kod:

#include <iostream>
#include <cmath>
using namespace std;


int main()
{
  double a, b, c, x1, x2;
  double s, d, signb;
  double p1,p2;
  double blad_bez_x1,blad_wzgl_x1;
  double blad_bez_x2,blad_wzgl_x2;
  double blad_wzgl;
  double z1,z2,v1,v2;
  
  cout << "Wprowadz pierwiastki: ";
  cin >> p1;
  cin >> p2;
  
  
  
  a = 1;
  b = (p1 * -1) - p2;
  c = p1 * p2;
	
  cout<<"\n" << "a: " << a << "\n" <<"b: " << b << "\n" <<  "c: " <<c<<"\n";


  d = b*b - 4*a*c;
  signb = 1;
  if(b < 0)
  {
  	signb = -1;
  }
  s = -(b + sqrt(d)*signb)/2;
  x1 = s/a;
  x2 = c/s;

  z1=((-1) * (b - sqrt(d))) / (2 * a);
  z2=((-1) * (b + sqrt(d)))/ (2 * a);
  
  v1=z1;
  v2=z2;
  cout<<"Pierwiastki niedokladne: "<<z1<<" "<<z2<<"\n";

  cout << "Pierwiastki dokladne: " << x1 << " " << x2 << "\n";
  
           blad_wzgl=((p1+p2)/(z1+z2)*100);

           cout<<endl;    
           cout.precision(2);
           cout<<"Skutecznosc: "<<fixed<<abs(blad_wzgl)<<" %"<<endl;  
          
  
}
1

Może spróbuj skorzystać z biblioteki boost, być może to pomoże.
https://www.boost.org/doc/libs/1_63_0/libs/math/doc/html/math_toolkit/float_comparison.html

1
Adiseeker napisał(a):
  z1=((-1) * (b - sqrt(d))) / (2 * a);
  z2=((-1) * (b + sqrt(d)))/ (2 * a);

Doprawdy? Polecam przestudiować https://pl.wikipedia.org/wiki/R%C3%B3wnanie_kwadratowe

#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;

int main()
{ 
	double p1,p2;
	cout.setf(ios::fixed);
	while(cin>>p1>>p2)
	{
		double a=1,b=-p1-p2,c=p1*p2,sd=sqrt(b*b-4*a*c);
		double z1=0.5*(-b-sd)/a,z2=0.5*(-b+sd)/a;
		cout<<"Pierwiastki niedokladne: "<<setprecision(16)<<p1<<" "<<setprecision(16)<<p2<<endl;
		cout<<"Pierwiastki dokladne:    "<<setprecision(16)<<z1<<" "<<setprecision(16)<<z2<<endl;
	}
	return 0;
}

https://ideone.com/owgTyh

1 użytkowników online, w tym zalogowanych: 0, gości: 1