Hoşgeldiniz!

Kayıt olarak, topluluğumuzun diğer üyeleri ile görüşebilir, paylaşabilir ve özel mesaj gönderebileceksiniz.

Şimdi Kayıt Ol!

C ile Kosinüs(cos) algoritması

snow

Administrator
Yönetici
Katılım
11 Ağu 2019
Mesajlar
11
Beğeniler
8
#1
C dilinde kosinüs algoritmasını yazabilmek için bilmemiz gereken bir temel matematik formülü vardır. Bu formülün basit gösterimi aşağıdaki gibidir.

media_d89_d898b7b5-5fe2-4773-946a-dd68ceb290c8_php5J3UXd.png

n=0 dan başlayıp adımlar 2 şerli olarak artarak ilerlemektedir.
Buradaki x değeri radyal bir değerdir. burayı açı olarak belirtmek istiyorsak.

index.png

formülünü kullanmamız gerekiyor.

kosinüs formülümüzü başka yerlerde de kullanabilmek için ayrı bir fonksiyon içerisinde yazalım.
Fonksiyonumumuzun tanımı aşağıdaki gibi olucaktır.
C:
double myCos(double rad);
fonksiyonumuz double tipinde geri dönüş yapıcak. ve radyal değerimiz 0-pi(~3.1415) arasında olucak(0-360 derece için). buyüzden fonksiyonun parametresi olarakta double tipinde bir değişken girdisi aldık.

Şimdi ilk olarak main fonksiyonumuza gelelim.
Kullanıcıdan bir açı girmesini isteyeceğiz. ve bu açının radyal değerini alıp kendi kosinüs fonksiyonumuz olan myCos içerisinde kullanarak kosinüs değerini hesaplayacağız.
ve bulduğumuz sonucu ekrana yazacağız.

C:
double deg, rad;
deg ve rad isminde iki adet double tipinde değişken oluşturuyoruz.

ardından kullanıcının deg değerini kendisinin belirlemesini sağlamak amacı ile scanf fonksiyonunu kullanacağız.
C:
printf("Derece girin: ");
scanf("%lf", &deg);
printf fonksiyonu ile kullanıcıdan basitçe ne tür bir değer girmesini istediğimizi belirttik ve scanf yardımı ile kullanıcının girmiş olduğu değeri deg değişkenine aktardık.

sıra girilen derecenin radyal karşılığını almaya geldi.
Yukarıdaki formülümüze bakarak aşağıdaki atamayı yapabiliriz.
C:
rad = (deg * PI) / 180;
rad değişkeninin değeride oluşturulduktan sonra artık kosinüs değerini hesaplamaya geldi sıra.

C:
double eq = myCos(rad);

printf("cos(%.2f) = %lf\n", deg, eq);
kosinüs değerini ekranda yazdırmak için eq isimli bir double türünde bir değişken oluşturduk. ve bu değişkenin içerisine myCos(rad) fonksiyonunun geri döndüreceği değeri kaydettik.
ardından kullanıcının hesaplanan değeri görebilmesi için sonucu ekrana yazdırdık.

Evet konunun asıl yeri olan kosinüs fonksiyonunun(myCos) içeriğine geldi sıra.

en başta belirtmiş olduğumuz formülün en doğru sonucu verebilmesi için son teriminin mutlak değeri 0.0001 den küçük olmalıdır.

C:
double eq = 1, temp = 1;
int i = 2;
eq değişkeninin içerisine bulduğumuz terimlerin toplamını kaydedeceğiz. Formülümüz değişkenden bağımsız olarak +1 değeri ile başladığından dolayı başlangıç değerini 1 olarak aldık.
temp değişkeninin içerisine bir sonraki terimi hesaplayabilmek için bir önceki terimin sonucunu kaydedeceğiz. bu değeride neden 1 aldığımızı aşağıda anlayacaksınız.
ve tam sayı olarak tanımladığımız i değişkenini 2 den başlattık.
Çünkü formülümüzün ilk terimi (x^2)/2!
i
değerini 1 den başlatsaydık yine aynı sonuca ulaşabilirdik. ancak neden 2 den başladığımızı aşağıda anlayacaksınız.

i değişkenini daha kolay saydırmak için for döngüsünden yararlanıyoruz.
C:
for (i;;i+=2){

}
bu döngünün bitiş ve başlangıç şartını belirtmiyoruz. bitiş şartını belirtmeme sebebimiz hesaplamayı bırakacağımızı dizinin son elemanının değerine göre karar vereceğiz.
i değişkenini her seferinde iki iki arttırıyoruz ve başlangıç değerini zaten değişkeni oluştururken belirttiğimiz için atamamıza gerek kalmadı. Dolayısıyla döngü içerisinde i değerimiz 2,4,6,8,10... şeklinde devam edecek.

bunu istememizin sebebi kosinüs formülünde x in kuvveti her terimde 2 artarak devam ediyor. ve faktöriyeller de her terimde 2!,4!,6!... şeklinde iki iki artarak devam ediyor.
Terimlerimiz bir negatif, pozitif, negatif, pozitif... şeklinde devam ediyor. ilk terimimiz negatif ile başlıyor. buyüzden ilk ifademizi -1 ile çarpmamız gerekiyor.
ilk terimin hesabı kabaca aşağıdaki gibi olucak.
C:
ilkterim = (-1) * (rad*rad)/2*1;
ikinci terimimiz ise aşağıdaki gibi olacaktır.
C:
ikinciterim = (1) * (rad*rad*rad*rad)/4*3*2*1;
iki terim arasındaki farkı görebiliyormusunuz?
ikinci terimi elde etmenin başka bir yolu daha var.
C:
ikinciterim = ilkterim * (-1) * (rad*rad)/4*3;
buradan anlaşılacağı üzere (n+1).terimi hesaplamak için n*(n-1) işlemini yapmamız yeterli oluyor.

yani biz her döngüde aşağıdaki komutu çalıştırırsak sıradaki terimin değerini bulabiliriz.
a *= 5; ifadesi ile a = a * 5; ifadesi birbirine eşittir.
*= ataması değişkenin kendisi ile eşitliğin sağ tarafının çarpımının değerini alır!
C:
temp *= (-1)*((rad*rad)/(i*(i-1)));
el ile ilk 3 terimi hesaplayacak olursak.
rad = 1; kabul edelim.
x1 = ilk terim, x2 = ikinci terim, x3 = üçüncü terim

x1 = (-1)*((1*1)/2*1) = -0.5
x2 = x1 * (-1)*((1*1)/4*3) = 0.04166 VEYA 1^4/4! = 0.04166
x3 = x2 * (-1)*((1*1)/4*3) = -0.001388 veya (-1)*1^6/6! = -0.001388

evet bu sağlama ile doğru yolda olduğumuzu teyit etmiş olduk.
sıradaki işlemimiz ise hesaplamış olduğumuz her terimi eq(sonucu aktardığımız değişken) içerisine eklemek.

bunun için basitçe:
a += 5; ifadesi ile a = a + 5; ifadesi birbirine eşittir.
+= ataması değişkenin kendisi ile eşitliğin sağ tarafının toplanmının değerini alır!
C:
eq += temp;
yazabiliriz.

döngümüz şuan sonsuza kadar hesap yapmaya devam edecek. bunun önüne geçmek için son hesapladığımız terimin değerini bulunduran temp değişkenini kontrol etmektir.
En başta belirttiğimiz gibi son terimin mutlak değeri 0.0001 den küçük olmalıdır. yani |temp| < 0.0001 ifadesini c dilinde if koşulu ile kontrol etmemiz gerekiyor.
math.h kütüphanesini kullanarak basitçe fabs(temp) < 0.00001 koşulunu yazabiliriz. ama math kütüphanesini kullanmazsak 4 farklı kontrol sağlamamız gerekiyor.

if koşulunun sözel ifadesi aşağıdaki gibidir:
Eğer:
temp 0 dan küçük ise ve temp > -0.00001 ise
veya
temp 0 dan büyük eşit ise ve temp < 0.00001 ise


şeklindedir.
bu ifadenin sağlanması durumda döngü kırılmalıdır. Ve bu ifadenin c karşılığı aşağıdaki gibidir.

C:
if((temp < 0 && temp > -0.00001) || (temp > 0 && temp < 0.00001))
    break;
artık döngüde kırıldığına göre geri yapılacak tek şey bulduğumuz sonucu return etmektir.

Konunun özeti olarak kodumuzun son hali aşaıdaki gibidir.
C:
#include <stdio.h>

#define PI 3.141592654

double myCos(double rad);

int main()
{
    double deg, rad;
    
    printf("Derece girin: ");
    scanf("%lf", &deg);
    rad = (deg * PI) / 180;
    
    double eq = myCos(rad);

    printf("cos(%.2f) = %lf\n", deg, eq);

    return 0;
}

double myCos(double rad){
    double eq = 1, temp = 1;
    int i = 2;
    for (i;;i+=2)
    {
        temp *= (-1)*((rad*rad)/(i*(i-1)));
        eq += temp;

        if((temp < 0 && temp > -0.00001) || (temp > 0 && temp < 0.00001))
            break;
    }
    return eq;
}

örnek konsol çıktısı:
Screenshot from 2019-11-14 15-33-15.png

şeklindedir.
 
Üst Alt