Sinus i cosinus

Odpowiedz Nowy wątek
2011-10-12 22:29
0

Jak policzyć sinus i cosinus z rozwinięć w szereg? Ile wyrazów mam zsumować?

user image
user image

public static double sinus(int x) {
        double sin = 1, sin1, sin2;
        for(int i = 1; i < 10; i++) {
            sin1 = x_do_n(x, (2*i +1) ) * x_do_n(-1, i);
            sin2 = k_silnia(2*i + 1);
            sin += sin1/sin2;
        }
        return sin;
    }

    public static double cosinus(double x) {
        double cos = 1, cos1, cos2;
        for(int i = 1; i < 10; i++) {
            cos1 = x_do_n(x, 2*i) * x_do_n(-1, i);
            cos2 = k_silnia(2*i);
            cos += cos1/cos2;
        }
        return cos;
    } 

Funkcje silnia i potęgowanie są poprawne.

//W podglądzie wyświetla mi obrazy - wzory..

edytowany 2x, ostatnio: squixy, 2011-10-12 22:31

Pozostało 580 znaków

2011-10-13 00:24
0

Jeżeli chcesz uzyskać dokładną wartość sinusa, to nieskończoność. Właściwie to do momentu w którym wynik dzielenia licznika przez mianownik dla komputera będzie równy 0.
Na wiki jest ładnie pokazana zależność między ilością iteracji, a dokładnością: http://pl.wikipedia.org/w/index.php?title=Plik:Sintay.svg
Wydaje mi się że jak dojdziesz już do x^13 to jest wystarczająco dokładne.

Nie używaj funkcji do silni. Skorzystaj z tego że n!=(n-2)!(n-1)n, albo najlepiej tablicuj wartości silni dla tylu iteracji ile użyjesz.
Pętle niech ci ułatwiają, to nie pascal i możesz inkrementować dowolnie, niekoniecznie o 1. Zacznij se od 3 i dodawaj po 2 i dopóki i<=13.
Potęgowanie -1 też nie wydaje mi się optymalnym pomysłem. Lepszym pomysłem jest coś takiego:

int znak=1;
for(/**/){
  znak*=-1;
}

Ewentualnie 2 wyrazy (tzn + i -) za jednym zamachem załatwić.

Pozostało 580 znaków

2011-10-13 01:16
0

Sumuj od najmniejszego do największego składnika, aby nie tracić precyzji na ostatnich bitach.

Dla przykładu, jeżeli mamy dwie cyfry znaczące, to:

Przy sumowaniu od najmniejszego:
0.05 + 0.05 + 1 = 0.1 + 1 = 1.1

Przy sumowaniu od największego:
1 + 0.05 + 0.05 = 1 + 0.05 = 1


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
Teoretycznie to powinieneś ze zbioru liczb do zsumowania zastępować dwie najmniejsze liczby ich sumą, dopóki nie zostanie jedna. - Zjarek 2011-10-13 08:46
Wiem, pisałem o tym nieraz na forum, ale w tym przypadku akurat będzie to raczej równorzędne z sumowaniem od końca. - Wibowit 2011-10-13 12:43

Pozostało 580 znaków

2011-10-13 11:11
1

zobacz, ani potęgowania ani silniowania

float Sin(float OOO){
        float O0O=OOO,OO0=OOO;OOO*=OOO;
        int  O00='/'/'/'<<001;
        while(O0O) 
                OO0-=O0O*=OOO/O00++/++O00,
        OO0+=O0O*=OOO/O00++/++O00; 
        return OO0;
} 
To chyba działa dla tylko pierwszej ćwiartki. No i czytelność pierwsza klasa. :) Szczególnie te cztery zmienne. Tyle, że to chyba w C/C++ bo O0O nie może być warunkiem w Javie. - Olamagato 2011-10-14 03:43
działa w całym litrze, a warunek może być taki (O0O!=000) - Xitami 2011-10-14 12:26

Pozostało 580 znaków

2011-10-15 09:59
0

W Javie oprócz warunku problemem w tej funkcji jest również przecinek, który nie pozwala skompilować kodu. Jeżeli sądząc po formatowaniu w jego miejscu powinien być średnik, to wyniki są takie:
sin(0) = 0,00
sin(30) = 0,51
sin(60) = 0,90
sin(90) = 1,03
sin(120) = 0,72
sin(150) = -0,37
sin(180) = -2,70
sin(210) = -7,08
sin(240) = -14,80
sin(270) = -27,96
sin(300) = -50,01
sin(330) = -86,63
sin(360) = -147,11

Kod testu:

public static void main(String[] args)
{
    double step = 2 * Math.PI / 12; //~30 st.
    for(float alpha = 0; alpha <= Math.PI * 2; alpha += step)
    {
        System.out.printf("sin(%.0f) = %.2f%n",
            alpha * 360 / (Math.PI * 2), Sin(alpha));
    }
}

Jak widać "znośne" wyniki są w pierwszej ćwiartce. W pozostałych nie działa prawidłowo.


Jeżeli ktoś komuś coś, ewentualnie nikt nikomu nic, to właściwie po co...?

Pozostało 580 znaków

2011-10-15 11:22
0

sens przecinka w C/C++ jest jasny, więc...

...Piszemy o Javie, która takiego operatora nie ma. A przynajmniej nie w takim zastosowaniu. Po jakiego więc grzyba dawać nieczytelny kod w innym języku? - Olamagato 2011-10-15 13:05

Pozostało 580 znaków

2011-10-15 15:57
0
float Sin(float OOO){
        float O0O=OOO,OO0=OOO;OOO*=OOO;
        int  O00='/'/'/'<<001;
        while(O0O!=000) 
                OO0+=O0O*=-OOO/O00++/++O00;
        return OO0;} 

A tak może być?

Pozostało 580 znaków

2011-10-16 19:45
0

Jeżeli takie wyniki jak poniżej są akceptowalne:
sin(0) = 0,00
sin(30) = 0,51
sin(60) = 0,91
sin(90) = 1,13
sin(120) = 1,14
sin(150) = 0,93
sin(180) = 0,57
sin(210) = 0,14
sin(240) = -0,27
sin(270) = -0,56
sin(300) = -0,69
sin(330) = -0,63
sin(360) = -0,42
to na pewno może. :)

Dla porównania używając metody Math.sin() dostajemy:
sin(0) = 0,00
sin(30) = 0,50
sin(60) = 0,87
sin(90) = 1,00
sin(120) = 0,87
sin(150) = 0,50
sin(180) = 0,00
sin(210) = -0,50
sin(240) = -0,87
sin(270) = -1,00
sin(300) = -0,87
sin(330) = -0,50
sin(360) = -0,00


Jeżeli ktoś komuś coś, ewentualnie nikt nikomu nic, to właściwie po co...?

Pozostało 580 znaków

2011-10-16 20:10
0

Do rozwiązania Xitami: lipa... preinkrementacja wartości O0O odbywa się jeszcze przed jakimikolwiek podstawieniami, tak więc np. dla O0O=2 wyrażenie

OO0+=O0O*=-OOO/O00++/++O00;

zostanie zamienione na OO0+=O0O*=-OOO/3/3


 i wtedy wszystko nawala (dla OOO=1 drugi wyraz powinien wynosić -1/6, w tym rozwiązaniu wynosi -1/9).

Not Found
The requested URL /wypasiona_sygnaturka.txt was not found in this brain.
-----
Human/1.0.00 (Earth) Server at Poland Port 65535

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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