Problemas ao calcular equacao de 2 grau

1. Problemas ao calcular equacao de 2 grau

luve
luv3

(usa Ubuntu)

Enviado em 22/02/2018 - 11:01h

Bom dia, preciso de ajuda para calcular uma equacao com uma certa precisao.

No problema é pedido que calculemos a seguinte equação: 10^-8x² - 0.8x + 10^-8.

Desenvolvi o seguinte código:

#include <iostream>
#include<cmath>
#include<iomanip>
#include<cstdlib>

int main(void)
{
long double a=0.00000001;
long double b=-0.8;
long double c=0.00000001;
long double delta=0;
long double x1=0;
long double x2=0;

delta=(b*b)-4*a*c;


std::cout<<"delta: "<<delta<<std::endl;

x1=(-b-std::sqrt(delta))/2*a;
x2=(-b+std::sqrt(delta))/2*a;

std::cout<<std::setprecision(3)<<x1<<std::endl;

std::cout<<"x2: "<<x2<<std::endl;
}



Mas não consigo chegar nas raizes que foram exigidas: (0.8)10^10 e (1.25)10^-8.


Eu gostaria de saber como trabalhar com melhor precisão.



  


2. Re: Problemas ao calcular equacao de 2 grau

Rodrigo
omag0

(usa Debian)

Enviado em 22/02/2018 - 13:23h

Pelo visto ta usando C né?
Qual o erro?


3. Re: Problemas ao calcular equacao de 2 grau

Paulo
paulo1205

(usa Ubuntu)

Enviado em 22/02/2018 - 14:06h

luv3 escreveu:

Bom dia, preciso de ajuda para calcular uma equacao com uma certa precisao.

No problema é pedido que calculemos a seguinte equação: 10^-8x² - 0.8x + 10^-8.

[Código suprimido por brevidade.]

Mas não consigo chegar nas raizes que foram exigidas: (0.8)10^10 e (1.25)10^-8.


Se você reconstituir a equação a partir das raízes desejadas, vai obter a equação x²-8.0000000000000000125·10^9·x+100, que não corresponde exatamente à equação original, nem mesmo multiplicando toda a equação por 10^(-8).

Eu gostaria de saber como trabalhar com melhor precisão.


Aumentar a precisão só das variáveis envolvidas no cálculo não vai ajudar pois, como se pode ver, aquelas raízes não são soluções exatas daquela equação.

O problema é que a notação de ponto flutuante com precisão finita não permite trabalhar ao mesmo tempo com números muito grandes e muito pequenos, pois o que é pequeno acaba sendo desprezado perto daquilo que é grande, por falta de bits suficientes para representá-los.

Aquele número que aparece na equação reconstituída a partir das raízes desejadas talvez já não possa mais ser representado como long double numa arquitetura que use 64 bits para a mantissa (N.B. no Linux é assim por padrão; no Windows com Visual Studio, o padrão é long double ser igual a double, com uma mantissa de apenas 52 bits, e você é obrigado a solicitar explicitamente que long double use maior precisão), pois esses 64 bits dão uma precisão decimal de 19.2 dígitos, e o valor de b já tem vinte dígitos (se eu não contei errado). Quando, então, você fizesse b*b para calcular o valor de delta, seriam necessários 40 ou 41 dígitos para calcular o valor exato, que o long double não tem, e você iria perder precisão, e essa perda ficaria ainda mais grave após subtrair 400 (da parte -4*a*c), e novamente não iria conseguir calcular com precisão as raízes.

Para conseguir fazer essas contas com a precisão que você quer, você teria de usar uma biblioteca ou sistema de computação com precisão arbitrária, em lugar dos tipos nativos com precisão limitada e fixa.


4. Re: Problemas ao calcular equacao de 2 grau

luve
luv3

(usa Ubuntu)

Enviado em 22/02/2018 - 14:21h

Sim, estou usando c++ no QTCREATOR.

paulo1205, então independente da modificação que eu faça no código não irá solucionar o problema, pois até mesmo a arquitetura influencia no resultado?


5. Re: Problemas ao calcular equacao de 2 grau

luve
luv3

(usa Ubuntu)

Enviado em 22/02/2018 - 14:28h

omag0 escreveu:

Pelo visto ta usando C né?
Qual o erro?


Uso c++, o problema é que não consigo chegar nas raizes: (0, 8)10^8 e (1, 25)10^-8




6. Re: Problemas ao calcular equacao de 2 grau

Luís Fernando C. Cavalheiro
lcavalheiro

(usa Slackware)

Enviado em 22/02/2018 - 18:46h

luv3 escreveu:

Bom dia, preciso de ajuda para calcular uma equacao com uma certa precisao.

No problema é pedido que calculemos a seguinte equação: 10^-8x² - 0.8x + 10^-8.

Desenvolvi o seguinte código:

#include <iostream>
#include<cmath>
#include<iomanip>
#include<cstdlib>

int main(void)
{
long double a=0.00000001;
long double b=-0.8;
long double c=0.00000001;
long double delta=0;
long double x1=0;
long double x2=0;

delta=(b*b)-4*a*c;


std::cout<<"delta: "<<delta<<std::endl;

x1=(-b-std::sqrt(delta))/2*a;
x2=(-b+std::sqrt(delta))/2*a;

std::cout<<std::setprecision(3)<<x1<<std::endl;

std::cout<<"x2: "<<x2<<std::endl;
}



Mas não consigo chegar nas raizes que foram exigidas: (0.8)10^10 e (1.25)10^-8.


Eu gostaria de saber como trabalhar com melhor precisão.


Considerando:
x' + x'' = ( -b / a )
x' * x'' = ( c / a )

A gente tem que:
x' * x'' = 10^-8 / 10^-8
x' * x'' = 1
x' = 1 / x''

Daí, temos que:
x' + x'' = ( -b / a)
x' + x'' = ( 8 * 10^-1 / 10^-8 )
x' + x'' = 8 / 10^-7
x' + x'' = 8 * 10^7
1 / x'' + x'' = 8 * 10^7
1 + x''^2 = 8 * 10^7 * x''
x''^2 - 8 * 10^7 * x'' + 1 = 0

Logo,
&#916;'' = ( -8 * 10^7 )^2 - 4 * 1 * 1
&#916;'' = 6,4 * 10^15 - 4

x'' = ( 8 * 10^7 ± &#8730; ( 6,4 * 10^15 - 4 ) ) / 2 * 1

Considerando que:
6,4 * 10^15 - 4 &#8773; 6,4 * 10^15
e
6,4 * 10^15 = 64 * 10^14

Temos que
x'' &#8773; ( 8 * 10^7 ± &#8730; ( 6,4 * 10^15 ) ) / 2
x'' &#8773; ( 8 * 10^7 ± 8 * 10^7 ) / 2
x''¹ &#8773; 2 / 2 = 1
x''² &#8773; 0 / 2 = 0

Considerando que
x' = 1 / x'' 

x''² deve ser descartado. Logo
x' &#8773; 1 / 1
x' &#8773; 1

O que nem em sonhos muito loucos corresponde às raízes dadas.

LEGENDA (pois descobri agora que o VOL não aceita caracteres unicode)
&#8773; = aproximadamente igual
&#8730; = sinal de radiciação
&#916; = delta

--
Dino®
IRC: luisfcc86@freenode.com
Vi veri universum vivus vici
Public GPG signature: 0x246A590B
Só Slackware é GNU/Linux e Patrick Volkerding é o seu Profeta
Mensagem do dia: Satã representa conhecimento sem limites e não auto-ilusão hipócrita. 


O Enigma do GNU/Linux
O Enigma do GNU/Linux sempre carregou consigo um mistério. Você deve aprender esse segredo, meu jovem. Você deve aprender sua disciplina. Pois em nada neste mundo você pode confiar. Não nas Debian-like, não nas RPM-based, não nas derivadas do Gentoo. Nisto [aponta para o cachimbo] você pode confiar.







Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts