[C] Wyznaczanie sinusa na podstawie szeregu Taylora

Midair
Użytkownik
Użytkownik
Posty: 4
Rejestracja: 3 lis 2012, o 17:10
Płeć: Mężczyzna
Lokalizacja: Warszawa

[C] Wyznaczanie sinusa na podstawie szeregu Taylora

Post autor: Midair »

Witam, muszę napisać program, który będzie wyznaczał wartości funkcji \(\displaystyle{ \sin (x)}\) z rozwinięcia w szereg potęgowy.

Użytkownik ma wprowadzić zmienne takie, jak:
\(\displaystyle{ x_p}\) - dolna granica \(\displaystyle{ x}\)
\(\displaystyle{ x_}\) - gorna granica \(\displaystyle{ x}\)
krok - z ktorym zwieksza sie \(\displaystyle{ x}\) i ma wyswietlac wynik sinusa co krok
dokladnosc - w procentach, ma ograniczac liczbe wyrazow szeregu potegowego.

Niestety są to moje początki i nie orientuję sie za bardzo jak się za to zabrać. Na razie mam coś takiego:

Kod: Zaznacz cały

#include <stdio.h>
#include <math.h>



main()
{
    printf("Podaj dolną granicę argumentu funkcji sin(x)
");
    scanf("%f", &xp);
    printf("Podaj górną granicę argumentu funkcji sin(x)
");
    scanf("%f", &xk);
    printf("Podaj krok z jakim następuje powiększanie wartości argumentu funkcji sin(x)
");
    scanf("%f", &krok);
    printf("Podaj dokładność obliczeń w procentach
");
    scanf("%f", &dokładność)
    
    int xp, xk, krok, dokładność
    
    x=xp;
    while (x<=xk) {
    printf("%d	%d
", x, sin(x))
    x=x+krok;
    }

    
    
}
Moje pytanie w tej chwili brzmi: w wyrazeniu while uzylem w printf funkcje sin(x), chcialbym ja gdzies zdefiniowac, ale nie wiem gdzie to zrobic w kodzie. Czy ktos moglby pomoc? Oraz czy program moze pobierac i przypisywac zmienne zanim ja je sam okreslilem, tak jak to jest u mnie?
Ostatnio zmieniony 3 lis 2012, o 18:28 przez Afish, łącznie zmieniany 1 raz.
Powód: Stosuj tagi.
Awatar użytkownika
steal
Użytkownik
Użytkownik
Posty: 1043
Rejestracja: 7 lut 2007, o 18:35
Płeć: Mężczyzna
Lokalizacja: Białystok|Warszawa
Podziękował: 6 razy
Pomógł: 160 razy

[C] Wyznaczanie sinusa na podstawie szeregu Taylora

Post autor: steal »

Kod: Zaznacz cały

int xp, xk, krok, dokładność
Średnik na końcu każdej linii kodu. Int jest zarezerwowane dla liczb całkowitych, co w tym przypadku jest błędnie użyte, bo \(\displaystyle{ x}\) oraz reszta zmiennych będą liczbami wymiernymi. A więc zadeklaruj je jako double.
Jeżeli masz napisać własną implementację funkcji sinus, to nazwij ją inaczej niż jest zdefiniowana w bibliotece math.h, np. double sinus(double x). Definiujesz ją pod blokiem funkcji main, wypisując również jej deklarację przed nią (f. main), czyli:

Kod: Zaznacz cały

#include<stdio.h>

double sinus(double x);

int main(){
    ...
}

double sinus(double x){
   ....
}
Ser Cubus
Użytkownik
Użytkownik
Posty: 1406
Rejestracja: 6 maja 2012, o 22:46
Płeć: Mężczyzna
Lokalizacja: Polska
Podziękował: 107 razy
Pomógł: 145 razy

[C] Wyznaczanie sinusa na podstawie szeregu Taylora

Post autor: Ser Cubus »

może się czepiam, ale printf to pozostałość z c (c++ jest kompatybilne wstecz). Chyba lepiej używać w twoim wypadku zwykłego

cout >> "Treść";
Awatar użytkownika
steal
Użytkownik
Użytkownik
Posty: 1043
Rejestracja: 7 lut 2007, o 18:35
Płeć: Mężczyzna
Lokalizacja: Białystok|Warszawa
Podziękował: 6 razy
Pomógł: 160 razy

[C] Wyznaczanie sinusa na podstawie szeregu Taylora

Post autor: steal »

@Ser Cubus - jakbyś nie zauważył, to w tym przypadku programujemy w C.
I jeżeli już mówimy o C++ to poprawne jest

Kod: Zaznacz cały

cout << "Tresc";
Afish
Moderator
Moderator
Posty: 2828
Rejestracja: 15 cze 2008, o 15:45
Płeć: Mężczyzna
Lokalizacja: Seattle, WA
Podziękował: 3 razy
Pomógł: 356 razy

[C] Wyznaczanie sinusa na podstawie szeregu Taylora

Post autor: Afish »

Ser Cubus pisze:c++ jest kompatybilne wstecz
Nie jest.
Ser Cubus
Użytkownik
Użytkownik
Posty: 1406
Rejestracja: 6 maja 2012, o 22:46
Płeć: Mężczyzna
Lokalizacja: Polska
Podziękował: 107 razy
Pomógł: 145 razy

[C] Wyznaczanie sinusa na podstawie szeregu Taylora

Post autor: Ser Cubus »

Ser Cubus pisze:może się czepiam, ale printf to pozostałość z c (c++ jest kompatybilne wstecz). Chyba lepiej używać w twoim wypadku zwykłego

cout << "Treść";
edit:
steal
racja, mój błąd. Nie zauważyłem, że chodzi o C
Midair
Użytkownik
Użytkownik
Posty: 4
Rejestracja: 3 lis 2012, o 17:10
Płeć: Mężczyzna
Lokalizacja: Warszawa

[C] Wyznaczanie sinusa na podstawie szeregu Taylora

Post autor: Midair »

Wielkie dzięki za wasze odpowiedzi, zdefiniowałem sobie funkcję silnia oraz double sinus, gdyż silnia jest mi potrzebna do wyliczania sinusa s szeregu Taylora -> . Chciałbym zapytać czy według was wszystko jest ok jak narazie i czy poprawnie zdefiniowałem funkcje?

Kod: Zaznacz cały

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

double sinus (double x, int n);
int silnia (int s);

int main()
{
    
}
int silnia (int s){
    int wynik silni = 1; 
    for (int i =2; i <= s; i++)
        wynik *= i;
    return wynik silni;
}

double sinus (double x, int n){
    int wynik sinusa = 1;
    for (int k = 1; k <= n; k = k++)
        wynik sinusa += pow(-1,n)/silnia(2n + 1) * pow(x,2n + 1);
    return wynika sinusa;
}
Awatar użytkownika
steal
Użytkownik
Użytkownik
Posty: 1043
Rejestracja: 7 lut 2007, o 18:35
Płeć: Mężczyzna
Lokalizacja: Białystok|Warszawa
Podziękował: 6 razy
Pomógł: 160 razy

[C] Wyznaczanie sinusa na podstawie szeregu Taylora

Post autor: steal »

Są błędy, ponieważ nazwa zmiennej nie może zawierać spacji, oraz w funkcji sinus zmienną wynik_sinusa deklarujesz jako liczbę całkowitą, a jak wiemy sinus przyjmuje wartości rzeczywiste od -1 do 1.
ksisquare
Użytkownik
Użytkownik
Posty: 132
Rejestracja: 1 cze 2012, o 07:04
Płeć: Mężczyzna
Lokalizacja: Polska
Pomógł: 15 razy

[C] Wyznaczanie sinusa na podstawie szeregu Taylora

Post autor: ksisquare »

Za użycie:
x := x + krok oraz
silnia
siadaj dwa.

A pitolenia o kompatybilnościach nie słuchaj.
Ostatnio zmieniony 30 lis 2012, o 20:25 przez Afish, łącznie zmieniany 1 raz.
Powód: Poprawa wiadomości.
Midair
Użytkownik
Użytkownik
Posty: 4
Rejestracja: 3 lis 2012, o 17:10
Płeć: Mężczyzna
Lokalizacja: Warszawa

[C] Wyznaczanie sinusa na podstawie szeregu Taylora

Post autor: Midair »

Kod: Zaznacz cały

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

double sinus (double x, int n);
int silnia (int s);

int main()
{
    printf("Podaj dolną granicę argumentu funkcji sin(x)
");
    scanf("%f", &xp);
    printf("Podaj górną granicę argumentu funkcji sin(x)
");
    scanf("%f", &xk);
    printf("Podaj krok z jakim następuje powiększanie wartości argumentu funkcji sin(x)
");
    scanf("%f", &krok);
    printf("Podaj dokładność obliczeń w procentach
");
    scanf("%f", &dokładność);
    
    double xp, xk, krok, dokładność, d;
    for (x = xp; x <= xp; x = x + krok);
        d = (sinus(x) - sin(x))/sin(x);
        while (1-d < dokładność){
        n = n + 1}
    

}
int silnia (int s){
    int wynik_silni = 1;
    for (int i =2; i <= s; i++)
        wynik *= i;
    return wynik_silni;
}

double sinus (double x, int n){
    float wynik_sinusa = 1;
    for (int k = 1; k <= n; k = k++)
        wynik_sinusa += pow(-1,n)/silnia(2n + 1) * pow(x,2n + 1);
    return wynika_sinusa;
}
Chcę, by zmienna n w funkcji double sinus rosła w pętli while, aż zostanie osiągnięta pożądana dokładność. Moje pytanie brzmi, czy ta zmienna zostanie teraz rozpoznana, jako to n, które użyłem w definicji funkcji double sinus?
royas
Użytkownik
Użytkownik
Posty: 363
Rejestracja: 24 sie 2012, o 09:27
Płeć: Mężczyzna
Lokalizacja: Cieszyn
Pomógł: 80 razy

[C] Wyznaczanie sinusa na podstawie szeregu Taylora

Post autor: royas »

Nie to tak nie zadziała.
funkcja sinus ma u Ciebie dwa parametry x i n, natomiast wywołujesz ją z jednym: x, takie coś nie przejdzie. Myślę, że zamienienie linii 21 i 22 oraz poprawienie wywołania sinus w pewnym stopniu załatwiło by to co chcesz.
Ale ogólnie wydaje mi się, że nie za dobrze chcesz to zrobić.
Bo załóżmy, że zdana dokładność będzie wymagała obliczania 100 wyrazów. Jak zadziała Twój algorytm:
obliczy 1 wyraz. sprawdzi dokładność
obliczy 2 wyrazy (z czego tylko jeden 1 nowy). sprawdzi dokładność.
obliczy 3 wyrazy (z czego tylko jeden 1 nowy). sprawdzi dokładność.
...
obliczy 100 wyrazów (z czego 99 obliczał już w poprzednim kroku). sprawdzi dokładność.
Widzisz, że wykonywanych jest bardzo dużo zbędnych obliczeń?
Bardziej powinno ty wyglądać tak:
sumaCzęściowa=pierwszyWyraz.
dopóki nie osiągniesz odpowiedniej dokładności dodaj do sumyCzęściowej kolejny wyraz szeregu.

Ogólnie możesz też zoptymalizować obliczenia kolejnych wyrazów: zamiast dla każdego wyrazu liczyć całą potęgę i całą silnię, możesz pamiętać ile wynosiły one dla poprzedniego wyrazu i po prostu domnażać do nich odpowiednio: \(\displaystyle{ x^2}\) i \(\displaystyle{ 2n+1}\).

Jeszcze jedna sprawa \(\displaystyle{ (-1)^n}\) to tylko matematyczny trick aby kolejne wyrazy na zmianę dodawać i odejmować. Liczenie potęgi nie jest fajne. Pomyśl jak to można uzyskać bez potęgi.
Midair
Użytkownik
Użytkownik
Posty: 4
Rejestracja: 3 lis 2012, o 17:10
Płeć: Mężczyzna
Lokalizacja: Warszawa

[C] Wyznaczanie sinusa na podstawie szeregu Taylora

Post autor: Midair »

Wielkie dzięki za rady, jednak zostało mi trochę mało czasu, także w przyszłych projektach bardziej się pomartwię najstosowniejszymi metodami. Czy zatem teraz zmienna n zostanie dobrze rozpoznana?

Kod: Zaznacz cały

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

double sinus (double x);
int silnia (int s);

int main()
{
    printf("Podaj dolną granicę argumentu funkcji sin(x)
");
    scanf("%f", &xp);
    printf("Podaj górną granicę argumentu funkcji sin(x)
");
    scanf("%f", &xk);
    printf("Podaj krok z jakim następuje powiększanie wartości argumentu funkcji sin(x)
");
    scanf("%f", &krok);
    printf("Podaj dokładność obliczeń w procentach
");
    scanf("%f", &dokładność);
    
    double xp, xk, krok, dokładność, d;
    for (x = xp; x <= xp; x = x + krok);
        while (1-d < dokładność){
            d = (sinus(x) - sin(x))/sin(x);
            n = n + 1;
            }
    

}
int silnia (int s){
    int wynik_silni = 1;
    for (int i =2; i <= s; i++)
        wynik *= i;
    return wynik_silni;
}

double sinus (double x, int n){
    float wynik_sinusa = 1;
    for (int k = 1; k <= n; k = k++)
        wynik_sinusa += pow(-1,n)/silnia(2n + 1) * pow(x,2n + 1);
    return wynika_sinusa;
}
royas
Użytkownik
Użytkownik
Posty: 363
Rejestracja: 24 sie 2012, o 09:27
Płeć: Mężczyzna
Lokalizacja: Cieszyn
Pomógł: 80 razy

[C] Wyznaczanie sinusa na podstawie szeregu Taylora

Post autor: royas »

Nie będzie dobrze. W ogóle próbujesz to kompilować czy tak na sucho tylko piszesz?
1. W main nie ma w ogóle zdefiniowanej zmiennej n. Nie nadajesz jej też wartości początkowej.
2. Nie przekazujesz aktualnej wartości zmiennej n do funkcji sinus - nie podajesz jej drugiego parametru.
ODPOWIEDZ