PDA

Tam Sürümünü Görmek İçin : Ondalık sayı sorunu


emre509
09/03/2008, 13:07
Arkadaşlar sizi meşgul ettiğim özür dilerim yine, hocamın verdiği bir ödev için çalışıyorum.İkinci dereceden tek bilinmeyenli bir denklemin köklerini döngü ile bulan C dilinde yazılmış bir programcık istedi bizden ben ise şöyle bir şeyler yaptım:
#include<stdio.h>
#include<math.h>//bunu bulunsun diye koydum, aslında gerek yok.

main()
{
float y,a,b,c,xmin,xmax,x,delta,step;
printf("Welcome to my Iterative Root Finding Program...\n");
printf("This program iteratively finds real roots of the polynomial\na*x^2 + b*x + c within a specified range\nEnter a: ");
scanf(" %f",&a);
printf("Enter b: ");
scanf(" %f",&b);
printf("Enter c: ");
scanf(" %f",&c);
printf("Enter x_min: ");
scanf(" %f",&xmin);
printf("Enter x_max: ");
scanf(" %f",&xmax);
printf("Enter stepsize: ");
scanf(" %f",&step);
delta=(b*b)-(4*a*c);

if(delta==0)
{
x=xmin;
while(x<xmax)
{
x=x+step;
y=(a*x*x)+(b*x)+c;
if(y==0)
{
printf("Here's the result\nRoot1: %f y:%f\n",x,y);
}}}

printf("Sorry, there is no root between your x_min and x_max values\n");

printf("Goodbye\n");
return 0;
}

1)Şimdi programa tüm değerleri biz giriyoruz, stepsize olarak 1, 2 -3 vb gibi ondalıksız şeyler yazınca çalışıyor ancak herhangi bir ondalık sayı yazınca(mesela 0.003 gibi) çalışmıyor, "Sorry, there is no root between your x_min and x_max values" mesajına atlıyor, hatta bazen öyle donup kalıyor.
2)Bir de delta>0 olunca yani iki kök bulması gerekince iki farklı döngü yaratmam gerekli mi yoksa program ilk kökü bulunca denemeyi bırakıyor.

Şimdiden teşekkürler
Not: Yanlış anlamayın, ödev çözümü istemiyorum sadece nerede yanlış yapıyorum onu bulamadım.


quasimodo
09/03/2008, 18:57
Programdaki xmin, xmax ne hicbir fikrim yok. Ayrıca kok bulma programinin neresinde dongu kullanilabilir ki?

VanlochMonster
09/03/2008, 21:41
Newton method una bak, turev alip kok bulmanin yonunu tayin etmelisin, Numerical Recipes veya herhangi bir numerik analiz kitabina basvurmani oneririm.

emre509
09/03/2008, 21:51
Arkadaşlar yanıtlarınız için teşekkür ederim ancak hocamız sadece bu methodu istiyor.Methodu açıklayayım.

Önce denklemin katsayılarını (a,b,c) girdik.Sonra denklemin köklerinin araştırılmasını istediğimiz bir aralık belirliyoruz x_min ve x_max ile.Son olarak da adım sayısını(stepsize) giriyoruz.Program x_min'den başlayarak x_max'a kadar adım sayısı kadar arttırıp, denkleme koyuyor eğer sağlanırsa "Root:" mesajı veriyor ve duruyor sağlanmazsa yinne bir step arttırp tekrar ediyor, x_max'a gidiyor bu döngü.

Programın son hali şöyle ve tam sayılarla her koşulda çalışıyor.Ancak herhangi bir değeri (a,b,c,xmin,xmax,step) ondalıklı girersek yada denklemin kökü ondalıklı çıkarsa yazdığım kök bulunamadı mesajı çıkıyor.Tek derdim ondalıklı durumlarda da çalışmasını sağlamak.

Kodların son hali ise şöyle:
#include<stdio.h>

int main()
{
float xmax,xmin,a,b,c,delta;
double y,x,step;
printf("Welcome to my Iterative Root Finding Program...\n");
printf("This program iteratively finds real roots of the polynomial\na*x^2 + b*x + c within a specified range\nEnter a: ");
scanf(" %f",&a);
printf("Enter b: ");
scanf(" %f",&b);
printf("Enter c: ");
scanf(" %f",&c);
printf("Enter x_min: ");
scanf(" %f",&xmin);
printf("Enter x_max: ");
scanf(" %f",&xmax);
if(xmin>xmax)
{ printf("Sorry, your 'x_min' value is greater than 'x_max', please type a logical range\n");}
if(xmin==xmax)
{ printf("Sorry, your 'x_min' value is equal to 'x_max', please type a logical range\n");}
else{
printf("Enter stepsize: ");
scanf(" %lf",&step);
delta=(b*b)-(4*a*c);


if(delta==0)
{
x=xmin;
while(x<xmax)
{
x=x+step;
y=(a*x*x)+(b*x)+c;
if(y==0)
{
printf("Here's the result\nRoot1: %.4lf\n",x);
return;}}
if(y!=0)
{
printf("Sorry, there is no root between your x_min and x_max values\n");
}
}
if(delta>0)
{
x=xmin;
while(x<xmax)
{
x=x+step;
y=(a*x*x)+(b*x)+c;
if(y==0)
{
printf("Here's the result\nRoot1: %.4lf\n",x);
while(x<xmax)
{
x=x+step;
y=(a*x*x)+(b*x)+c;
if(y==0)
{
printf("Root2: %.4lf\n",x);

return;}}}}
if(y!=0)
{
printf("Sorry, there is no root between your x_min and x_max values\n");
}}
if(delta<0)
{printf("Sorry, there is no real root in your polynomial\n");}


}

printf("Goodbye\n");
return 0;
}

golgepapaz
09/03/2008, 22:34
Buyuk harflerle,

ASLA FLOAT DEGERLERI ESITLIK ICIN KARSILASTIRMAYIN.

aciklamak gerekirse, float degerler bir yakinlastirma oldugundan bilgisayarda tam olarak ifade edilemezler. bu yuzden iki float degeri karsilastirirken birbirlerine bir esik degerinden daha yakin olup olmadiklarina bakman gerekir.bunu bir c fonksiyonu olarak ifadec edersek

bool float_equality(float a, float b, float epsilon)

burda a ve b karsilastiracagin iki deger epsilon ise iki sayiyi birbirine esit kabul edebilecegin maximum esik degeri (mesela epsilon=0.000001)
bu durumda fonksiyonun icini yazarsak
bool float_equality(float a, float b, float epsilon)
{
return fabs(a-b) < epsilon;
} (Google fabs eger ne oldugunu bilmiyorsan)

sana iki degerin milyonda bir den daha kucuk derecede fark ettigini soyleyecektir eger bu sana yetiyorsa tabi.

Gerci senin kodunda durum daha feci ve kullanicin insafina kalmis durumda
mesela xmin=0 xmax=1 diyelim(koklerden birinin bu aralikta oldugunu kabul edelim) stepsize da 0,01 olsun. bu durumda epsilon'un bu stepler arasinda koku yakalayabilmesi icin, epsilonunda buyuk bir rakam olmasi lazim(mesele 0,015 bir kok ise , 0,010 ile 0,020 islemlerinin sonucu 0 dan epsilonun oldugundan uzak olabilir) ama cok buyuk olursada yanlis koku bulabilir (0,01 ile 0,02 degerlerinin ikiside 0 a epsilondan daha yakin bir deger olusturabilir) bu durumda stepsize in yeterince kucuk olmasina dikkat etmek ve epsilonu da buna gore secmen gerekiyor

Umarim yardimci olmustur