1 Ostatnio edytowany przez tebe (2006-07-22 18:10:55)

mam takie pytanko, jak wyliczyć sinusa mając do dyspozycji operacje na liczbach zmiennoprzecinkowych typu dodawanie, odejmowanie, mnożenie, dzielenie, ogólnie mając do dyspozycji operacje z pakietu matematycznego Atari

zaglądałem już do źródeł takiej procedury z BASIC'a, może ktoś zna szybszy sposób czy też może przedstawić całą operację wyliczenia sinusa w postaci jakiegoś wzoru, tylko proszę bez szeregów potęgowych czy funkcji różniczkowych

w pakiecie matematycznym Atari znajdują się takie wartości

; POLYNOMIAL FOR SIN/COS FUNCTIONS (11 COEFFICIENTS)

PLYSIN    .he    3E 16 05 44 49 00 ;  1.6054449E-03  REF BY BASIC SIN/COS ROUTINES
    .he    BE 95 68 38 45 00 ; -9.5683845E-03
    .he    3F 02 68 79 94 16 ;  0.0268799416
    .he    BF 04 92 78 90 80 ; -0.049278908
    .he    3F 07 03 15 20 00 ;  0.0703152
    .he    BF 08 92 29 12 44 ; -0.0892291244
    .he    3F 11 08 40 09 11 ;  0.1108400911
    .he    BF 14 28 31 56 04 ; -0.1428315604
    .he    3F 19 99 98 77 44 ;  0.1999987744
    .he    BF 33 33 33 31 13 ; -0.3333333113
NONE    .he    3F 99 99 99 99 99 ;  0.9999999999   ALMOST EQUAL TO 1.0 (USED FOR ROUNDOFF PROBLEM)

; SIN OF 45 DEG.
SIN45    .he    3F 78 53 98 16 34 ; 0.7853981634

ktoś wie jak to ugryźć, czy to jest potrzebne aby wyliczyć sinus-a, bo Basic używa jakichś swoich predefiniowanych wartości

*- TeBe/Madteam
3x Atari 130XE, SDX, CPU 65816, 2x VBXE, 2x IDE Plus rev. C

2 Ostatnio edytowany przez tebe (2006-07-22 21:47:06)

chyba jednak to wydaje się najprostszym rozwiązaniem

sin x=x - x^3/3! + x^5/5! + x^7/7! + ...

*- TeBe/Madteam
3x Atari 130XE, SDX, CPU 65816, 2x VBXE, 2x IDE Plus rev. C

3

Sinusa najlepiej wyliczyć odczytując go z lookupa. :) Jak nie ma lookupa, to szereg potęgowy dość ładnie zbiega - BASIC stosuje tę metodę.

Lookupa można natomiast wyliczyć z zależności trygonometrycznych. Najprościej chyba z cos(a+b) - potrzebny poprzedni cos i jeden cos jako stała. Kiedyś to robiłem przy użyciu FP. Procka zajmowała z 70 bajtów, dawała ładnego "SIN-usa" i korzystała chyba tylko z dodawania (odejmowania?) FP i konwersji na int. Z tą konwersją trzeba uważać, bo chyba nie chwyta liczb ujemnych. :( Niestety policzenie 256 wartości trwało z pół minuty.

https://www.youtube.com/watch?v=jofNR_WkoCE

4

chyba mówimy o tym samym zbiorze przykładów wykorzystujących FP, rzeczywiście był tam błąd przy konwersji na ASCII, po poprawce chwyta minusy prawidłowo

dla szeregu potęgowego w/w są pewne odchyły od wartości idealnej, np.

sin(30) = 0.500000001
szereg sin(30) = 0.499674179

sin(37) = 0,6018150231
szereg sin(37) = 0.600888394

szereg wyliczany w krótki sposób sinx = x - x^3/3!

jest to zadowalająca precyzja ?


sinus wg zależności trygonometrycznych, będę musiał poszukać więcej danych na ten temat, może być ciekawiej :)

*- TeBe/Madteam
3x Atari 130XE, SDX, CPU 65816, 2x VBXE, 2x IDE Plus rev. C

5

Ja nie mówiłem o żadnym zbiorze przykładów ani o konwersji na ASCII tylko na liczbę całkowitą.

Dwa wyrazy szeregu to zdecydowanie za mało, żeby to przypominało sinusa.
Szereg lepiej liczyć bez potęgowania, np. ((x + a) * x + b) * x + c, nawet BASIC tak robi. :)

Z zależności trygonometrycznych dostaniesz dobrą precyzję.

https://www.youtube.com/watch?v=jofNR_WkoCE

6 Ostatnio edytowany przez tebe (2006-07-22 23:25:28)

Fox masz może jeszcze gdzieś swój program wyliczający sinusa z tych zależności trygonometrycznych ?

wzory redukcyjne sa np. tutaj http://www.wsipnet.pl/oip/msl/cz2/u/wt.html

Da sie w ten sposob przedstawic wszystkie stopnie, tyle ze trzeba na końcu znać wartości dla sinusa i cosinusa dla stopni 0..90

*- TeBe/Madteam
3x Atari 130XE, SDX, CPU 65816, 2x VBXE, 2x IDE Plus rev. C

7

Fox napisał/a:

Szereg lepiej liczyć bez potęgowania, np. ((x + a) * x + b) * x + c, nawet BASIC tak robi. :)

pod X podstawiamy kąt dla którego liczymy sinusa, a co podstawiamy pod A,B,C ? dlugosci odpowiednich ramion trójkąta ?

*- TeBe/Madteam
3x Atari 130XE, SDX, CPU 65816, 2x VBXE, 2x IDE Plus rev. C

8 Ostatnio edytowany przez tebe (2006-07-23 13:53:15)

n/w procedura liczy SINusa dla kąta podanego w radianach (kąt podajemy w zmiennej Angle, wynik także odczytujemy z Angle)

Sin:

S1 = Angle
Angle = Angle * Angle
S2 = Angle
Angle = Angle * 0.0138888889
Angle = Angle - 1
Angle = Angle * S2
Angle = Angle * 0.0238095242
Angle = Angle + 1
Angle = Angle * S2
Angle = Angle * .05
Angle = Angle - 1
Angle = Angle * S2
Angle = Angle * 0.166666671
Angle = Angle + 1
Angle = Angle * S1

najważniejsze że działa prawidłowo i podaje wyniki z tą samą dokładnością co Basic, nie ma żadnego potęgowania jednak jest sporo mnożeń

p.s.
stąd to wziąłem http://www.edw.com.pl/pdf/k10/58_03.pdf

*- TeBe/Madteam
3x Atari 130XE, SDX, CPU 65816, 2x VBXE, 2x IDE Plus rev. C

9

Jakiego znowu trójkąta? To współczynniki szeregu Maclaurina. Chodzi o to, żeby uniknąć potęgowania X.

Tworzenie lookupa wygrzebałem takie (jak widać potrzebne mnożenie):

     org $8000

fld0 equ $dd89
fld1 equ $dd98
fadd equ $da66
fsub equ $da60
fmul equ $dadb
fpi  equ $d9d2

     ldx #2
msin txa
     pha
     ldx <cos2
     ldy >cos2
     jsr fld0
     ldx <s1
     ldy >s1
     jsr fld1
     jsr fmul
     ldx <s2
     ldy >s2
     jsr fld1
     jsr fsub
     ldx #5
     lda s1,x
     sta s2,x
     lda $d4,x
     sta s1,x
     dex
     bpl *-13
     ldx <dsin
     ldy >dsin
     jsr fld1
     jsr fadd
     jsr fpi
     pla
     tax
     lda $d4
     sec
     sbc #127
     sta sin,x
     inx
     bne msin
     rts

dsin dta b($41),b($01),b($27),b($00),b($00),b($00)
cos2 dta b($40),b($01),b($99),b($93),b($97),b($64)
s1   dta b($40),b($03),b($11),b($67),b($36),b($02)
s2   dta b($00),b($00),b($00),b($00),b($00),b($00)

     org $600
sin  dta b(0)
     dta b(0)

     end

Miałem lepsze tylko teraz to nie znajdę.

https://www.youtube.com/watch?v=jofNR_WkoCE

10

thx Fox, potestuje Twój programik

p.s.
tam gdzie jest BPL *-13 powinno być BPL *-12

*- TeBe/Madteam
3x Atari 130XE, SDX, CPU 65816, 2x VBXE, 2x IDE Plus rev. C

11 Ostatnio edytowany przez Fox (2006-07-23 14:09:24)

tebe napisał/a:

najważniejsze że działa prawidłowo i podaje wyniki z tą samą dokładnością co Basic, nie ma żadnego potęgowania jednak jest sporo mnożeń

Nie sprawdzałem, ale mógłbym się założyć, że Atari BASIC daje dokładniejsze wyniki.

tebe napisał/a:

stąd to wziąłem http://www.edw.com.pl/pdf/k10/58_03.pdf

Na '51 to programowałem kiedyś kalkulator - z szeregu liczył tylko exp i log, ale jakby dopisać współczynniki to z sin i cos też by nie było problemu.

tebe napisał/a:

tam gdzie jest BPL *-13 powinno być BPL *-12

W ogóle nie powinno być "*-", tylko etykieta. Program działał, tylko przed wysłaniem posta zamieniłem indeksowanie Y na X zapominając o tym *!@#@ "*-".

https://www.youtube.com/watch?v=jofNR_WkoCE

12

Fox napisał/a:

To współczynniki szeregu Maclaurina. Chodzi o to, żeby uniknąć potęgowania X.

a jak te współczynniki można wyliczyć ?

*- TeBe/Madteam
3x Atari 130XE, SDX, CPU 65816, 2x VBXE, 2x IDE Plus rev. C

13

Foxowi zapewne chodziło o schemat Hornera przy rozwijaniu szeregu Maclaurina Jestem prawie pewny, że po zastosowaniu algorytmu hornera dostaniesz to samo co w poscie #8

14

Dzięki, nie wiedziałem, że to się nazywa schemat Hornera.

tebe napisał/a:

chyba jednak to wydaje się najprostszym rozwiązaniem

sin x=x - x^3/3! + x^5/5! + x^7/7! + ...

Wystarczy, że wykonasz na tym przekształcenia z podstawówki (wyłączasz x i kilka razy x^2).

https://www.youtube.com/watch?v=jofNR_WkoCE

15 Ostatnio edytowany przez tebe (2006-07-24 17:32:31)

tak juz zrobiłem, przekształciłem to i wyszło z tego 6 mnożeń

jednak na chwile obecna przepisałem na asm wersje z posta #8, czyli z 9 mnożeniami, jest ona dokładniejsza, wyliczenie sinusa zajmuje 5 ramek (standardowy pakiet FP Atari, na FastChip-ie powinno być szybciej)

wersje Taylora też zamienie na asm, zobacze ile oszczędze czasu na tych 3 mnożeniach mniej

p.s.
na FastChip-ie trwa to średnio 2 ramki

*- TeBe/Madteam
3x Atari 130XE, SDX, CPU 65816, 2x VBXE, 2x IDE Plus rev. C

16

A ja kiedyś napisałem procedurkę na podstawie takiego wzorku:   cos(k)=2 * cos(2a/n) * cos(k-1) - cos(k-2) gdzie n jest długością okresu
To zdaje się jest rekursywna synteza sinusa. Niestety źródłówka jest gdzieś na jednej, z moich tradycyjnych dyskietek :(

17

A świstak siedzi i zawija...

Sikor umarł...

18

tebe napisał/a:

wyliczenie sinusa zajmuje 5 FPS

Mógłbyś rozszyfrować "FPS" ?

https://www.youtube.com/watch?v=jofNR_WkoCE

19 Ostatnio edytowany przez laoo/ng (2006-07-24 09:55:12)

że pięc obliczeń na sekunde pewnie :)
Defacto to jest brzydka jednostka. Prawdziwi atarowcy powinni używać ramek ;)

20

Albo obrotów licznika.

Czy możecie wyjaśnić, Stirlitz, dlaczego wasz służbowy adres stirlitz@rsha.gov.de ma aliasa justas@gru.su?
Nie czytam PM. Proszę używać e-mail.

21

laoo/ng napisał/a:

Prawdziwi atarowcy powinni używać ramek ;)

U nas na wsi mówiło się też "wiadro". 2 wiadra to jedna ramka.

(to było chyba od "mam jeszcze wiadro czasu", czyli pół ramki).

http://www.5oft.pl/

22

Proponuję więc "Facts Per Second". 5 Facts Per Second równa się 0,1 Facts Per Frame.

KMK
? HEX$(6670358)

23

Pożyteczna jest też jednostka "tyle" (tu gest rękoma), przy czym może być "tyle" i "tyyyyle". W bardziej szczegółowej rozmowie "tyle" pokazuje się na ekranie.

Mniej popularna jednostka czasu to "kilocykl".

https://www.youtube.com/watch?v=jofNR_WkoCE

24

ale o co chodzi przecież napisałem ramki a nie fps (frame per second) :P

*- TeBe/Madteam
3x Atari 130XE, SDX, CPU 65816, 2x VBXE, 2x IDE Plus rev. C

25

Witam !

A może Panowie zaimplementowalibyście algorytm cordic.
Opiera się on na samych operacjach dodawania i rotacji.

http://vidmo.net/~balois/atari/cordic/

Na początek proponuje obejrzeć prezentację cordic.ppt

Pozdrawiam
Balois