Sinus i cosinus

Sinus i cosinus
SQ
  • Rejestracja:około 14 lat
  • Ostatnio:ponad 8 lat
  • Postów:7
0

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

user image
user image

Kopiuj
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
R9
  • Rejestracja:ponad 14 lat
  • Ostatnio:prawie 11 lat
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:

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

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

Wibowit
  • Rejestracja:około 20 lat
  • Ostatnio:około 6 godzin
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.
ZJ
Teoretycznie to powinieneś ze zbioru liczb do zsumowania zastępować dwie najmniejsze liczby ich sumą, dopóki nie zostanie jedna.
Wibowit
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.
Xitami
  • Rejestracja:ponad 20 lat
  • Ostatnio:ponad rok
1

zobacz, ani potęgowania ani silniowania

Kopiuj
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;
} 
Olamagato
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.
Xitami
działa w całym litrze, a warunek może być taki (O0O!=000)
Olamagato
  • Rejestracja:ponad 16 lat
  • Ostatnio:około 2 miesiące
  • Lokalizacja:Polska, Warszawa
  • Postów:1058
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:

Kopiuj
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...?
Xitami
  • Rejestracja:ponad 20 lat
  • Ostatnio:ponad rok
0

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

Olamagato
...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?
Xitami
  • Rejestracja:ponad 20 lat
  • Ostatnio:ponad rok
0
Kopiuj
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ć?

Olamagato
  • Rejestracja:ponad 16 lat
  • Ostatnio:około 2 miesiące
  • Lokalizacja:Polska, Warszawa
  • Postów:1058
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...?
MX
  • Rejestracja:około 17 lat
  • Ostatnio:około 13 lat
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

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

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

Kopiuj
 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

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.