ATNEL tech-forum https://forum.atnel.pl/ |
|
Tablica wartości funkcji utworzona preprocesorem https://forum.atnel.pl/topic3419.html |
Strona 1 z 1 |
Autor: | Krauser [ 29 cze 2013, o 17:50 ] |
Tytuł: | Tablica wartości funkcji utworzona preprocesorem |
![]() Przeglądając sieć natrafiłem na fajny trik. Typowe podejście na tablicę wartości funkcji wygląda tak, że chcąc skorzystać z przykładowo sinusa, dołączamy do programu kod np. z tej strony albo sami obliczamy to w arkuszu kalkulacyjnym i przenosimy łatwiej lub trudniej do kodu programu. Można to zrobić też jak pokazano poniżej: Plik main.c: język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
Plik values.txt: język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
Jeśli tak jak w przykładzie potrzeba 24 wartości sinusa to w pliku values.txt 24 razy powtarza się dokładnie tą samą linię. Parametr __LINE__ zwraca numer linii (tutaj 1-24). Jako, że zaczyna się numeracja od 1 to we wzorze na sinus odejmowana jest najpierw 1 i wtedy argument ma wartość 0-23. Przeliczając to na stopnie mnoży się razy krok czyli 15, bo akurat potrzeba 24 wartości z całego zakresu 0-360 stopni. Następnie konieczna jest zamiana stopni na radiany (/180.0*M_PI) dlatego, że funkcja sinus na takich wartościach operuje. Kolejnym krokiem jest dopasowanie wyniku do wartości 0-255 co jest realizowane poprzez pomnożenie razy 128 i dodanie 127. No i już nie potrzeba korzystać z innych programów ![]() |
Autor: | mirekk36 [ 29 cze 2013, o 18:56 ] |
Tytuł: | Re: Tablica wartości funkcji utworzona preprocesorem |
O matko ![]() ![]() ![]() a jak zaskoczyłem ![]() rezultatem tego myku jest fakt że, tzn postaram się to podsumować tak na mój rozum: 1. w programie nie zostaną użyte funkcje zmiennoprzecinkowe z math.h ![]() 2. w programie zostanie stworzona ładna tablica sinusów w pamięci FLASH 3. a wartości tej tablicy przygotuje grzecznie sługa PREPROCESOR ![]() 4. plik values.txt jest tylko taki pomocniczy .... ![]() ![]() dobrze myślę ? jeśli tak to działa to na prawdę Krauser super mega TRICK obczaiłeś w necie ! ![]() no i super że się nim podzieliłeś |
Autor: | SunRiver [ 29 cze 2013, o 18:58 ] |
Tytuł: | Re: Tablica wartości funkcji utworzona preprocesorem |
Ano właśnie ... kiedyś to widziałem i gdzieś przepadło w przepastnych czeluściach sieci zaiste . dzięki za przypomnienie , bo robienie na piechotę czasem dobija ![]() |
Autor: | jachu [ 29 cze 2013, o 19:58 ] |
Tytuł: | Re: Tablica wartości funkcji utworzona preprocesorem |
genialne ![]() |
Autor: | chodzikman [ 29 cze 2013, o 20:29 ] |
Tytuł: | Re: Tablica wartości funkcji utworzona preprocesorem |
Ja ostatnio spotykając się z tym problemem, mając naprawdę mało czasu napisałem sobie po prostu programik który generował kod. Generuje on sinusy o 6 różnych amplitudach w dwuwymiarowej tablicy i nie ma problemu z wygenerowaniem za pomoca tego kodu innych funkcji z math.c po lekkim przerobieniu, treść jego jest taka: język cpp
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
Pod linuksem odpalam skompilowany program np. Kod: ./sinus_gen > sinus.h więc nie potrzebuje zapisu do pliku, ale pod windowsem mogłoby się to przydać. Ponieważ miałem problemy z przetwornikiem, dodatkowo zrobiłem opcję generowania przebiegu do matlaba, aby porównać sobie tablicę do tego, co widze na oscyloskopie. Wykorzystanie preprocesora napewno jest bardziej "hackerskie", ale i trudniejsze w zrozumieniu (chociaż mnie strasznie podobają się takie tricki ![]() |
Autor: | krz [ 29 cze 2013, o 22:22 ] |
Tytuł: | Re: Tablica wartości funkcji utworzona preprocesorem |
@mirekk36 Te wartości nie znajdą się tam w magiczny sposób, bez wywołania funkcji sin(x) z biblioteki math. Mniej więcej będzie to wyglądać tak: 1. Preprocesor wpierw zamieni __LINE__ w pliku values.txt na odpowiadające im numery linii 2. Następnie w miejsce #include "values.txt" wklei zawartość tego pliku czyli: Kod: const uint8_t sin_tab[TAB_SIZE] PROGMEM ={ VALUE(1), VALUE(2), ..., VALUE(24), }; 2. Wszystkie miejsca gdzie użyte jest makro VALUE(a) przed kompilacją zamieni na: Kod: const uint8_t sin_tab[TAB_SIZE] PROGMEM ={ (sin( ( ( (1-1) * STEP )/180.0 )*M_PI )*128 + 127 ), (sin( ( ( (2-1) * STEP )/180.0 )*M_PI )*128 + 127 ), ..., (sin( ( ( (24-1) * STEP )/180.0 )*M_PI )*128 + 127 ), }; 3. Kompilator wygeneruje kod w asemblerze, który inicjalizuje tę tablicę, czyli do każdej wartości z tablicy przypisze wartość otrzymaną po wywołaniu tego wyrażenia. Tak przy okazji wydaje mi się, że ten wzór na zamianę <-1.0f, 1.0f> na <0, 255> jest zły. Jak sin(x) wyjdzie -1 to otrzymasz (-1.0f)*128 + 127 => -128.0f + 127 => -1.0f i po rzutowaniu na unsigned short int wyjdzie 255. Imo lepiej użyć wzoru: Kod: (sin((a-1)*STEP*PI/180.0f)*127.5f + 127.5f) Wg mnie zamiast kombinować z takimi hackami lepiej jest po prostu wygenerować sobię tę tablicę i ręczne przekleić do kodu. Niestety takie stuczki zmniejszają czytelność i jak nie znamy dokładnego zachowania kompilatora to mogą prowadzić do powstania błędów w programie. |
Autor: | mirekk36 [ 29 cze 2013, o 23:46 ] |
Tytuł: | Re: Tablica wartości funkcji utworzona preprocesorem |
krz napisał(a): Te wartości nie znajdą się tam w magiczny sposób, bez wywołania funkcji sin(x) z biblioteki math Nie pisałem, że magiczny ![]() Dobrze, że rozpisałeś to po swojemu w punktach bo dzięki temu jeszcze łatwiej będzie zrozumieć ideę działania tego tricku wielu ludziom ![]() krz napisał(a): Wg mnie zamiast kombinować z takimi hackami lepiej jest po prostu wygenerować sobię tę tablicę i ręczne przekleić do kodu łeeeej ![]() krz napisał(a): Niestety takie stuczki zmniejszają czytelność i jak nie znamy dokładnego zachowania kompilatora to mogą prowadzić do powstania błędów w programie To by oznaczało, że w zasadzie jak coś wygląda dziwnie - to lepiej tego nie ruszać. To jest dla osób które już zaskoczą o co tu chodzi - a myślę że sporo zaskoczy dzięki temu całemu wątkowi ... i nic nie będzie się działo ze zmniejszeniem czytelności kodu ![]() ![]() |
Autor: | Krauser [ 30 cze 2013, o 11:15 ] |
Tytuł: | Re: Tablica wartości funkcji utworzona preprocesorem |
krz napisał(a): Tak przy okazji wydaje mi się, że ten wzór na zamianę <-1.0f, 1.0f> na <0, 255> jest zły. Jak sin(x) wyjdzie -1 to otrzymasz (-1.0f)*128 + 127 => -128.0f + 127 => -1.0f i po rzutowaniu na unsigned short int wyjdzie 255. Imo lepiej użyć wzoru: Kod: (sin((a-1)*STEP*PI/180.0f)*127.5f + 127.5f) Tak wzór jest zły (pozdrawiam panią od matematyki ![]() język c Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod. Teraz wartości są jak te z arkusza po zaokrągleniu. Dodanie do wzoru 360 nic nie zmienia, ale wtedy obie wartości dla 0 i 180 stopni są równe i wynoszą 128 (jak w arkuszu kalkulacyjnym). Chociaż z drugiej strony bardziej symetryczne wyniki są, gdy dla 180 mamy wartość 127. Co kto woli. Środek jest na poziomie 127,5, a takiej wartości nie można wybrać. Zwiększenie rozdzielczości do 16 bitów też nic nie zmieni, bo znowu środek jest na poziomie 511,5 . |
Autor: | rafrew [ 15 wrz 2013, o 20:05 ] |
Tytuł: | Re: Tablica wartości funkcji utworzona preprocesorem |
Czy da się się w tym "tricku" podstawić inną funkcję zamiast sinusa z math.h? Konkretnie chodzi mi o funkcję przez siebie zdefiniowaną spoza biblioteki standardowej.? |
Autor: | Krauser [ 15 wrz 2013, o 20:39 ] |
Tytuł: | Re: Tablica wartości funkcji utworzona preprocesorem |
Zauważ, że: język c Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod. to nie jest po prostu: język c Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod. Można używać innych makr (makro to nie funkcja, ale może ją zastąpić) np. |
Autor: | rafrew [ 15 wrz 2013, o 20:53 ] |
Tytuł: | Re: Tablica wartości funkcji utworzona preprocesorem |
Czy chcesz powiedzieć, że preprocesor umie policzyć wartość sinusa z liczby? Raczej nie. Zakomentowanie lini #include<math.h> spowoduje błędy, zatem wartość sinusa obliczana jest na podstawie algorytmu zawartego w bibliotece math.h. Cytuj: Zauważ, że: Składnia: [ Pobierz ] [ Ukryj ] język c #define VALUE(a) (sin( ( ( (a-1) * STEP)/180.0 )*M_PI )*127.5 + 128 )/* wzór na wartość sinusa */ GeSHi to nie jest po prostu: Składnia: [ Pobierz ] [ Ukryj ] język c #define VALUE(a) (sin(a)) w sumie pierwsze sprowadza się do drugiego |
Autor: | mirekk36 [ 15 wrz 2013, o 20:59 ] |
Tytuł: | Re: Tablica wartości funkcji utworzona preprocesorem |
rafrew napisał(a): Czy chcesz powiedzieć, że preprocesor umie policzyć wartość sinusa z liczby? Kolego naprawdę poczytaj troszkę o preporcesorze gdzieś ![]() Co to za problem dla preprocesora obliczyć sin czy podobną funkcję - na PC? miałby to być kłopot ? a makro VALUE() działa tu TYLKO i wyłącznie w taki sposób że zwraca stałą dosłowną która zostanie wyliczona przez preprocesor właśnie |
Autor: | rafrew [ 15 wrz 2013, o 21:25 ] |
Tytuł: | Re: Tablica wartości funkcji utworzona preprocesorem |
Ok, jeśli tak to już wszystko jasne. Faktycznie muszę coś poszukać bo o funkcjach jakie umie wyliczyć preprocesor jakoś nigdzie się nie natknąłem. Dzięki za odpowiedzi. Pozdrawiam. |
Autor: | karolek [ 11 lut 2014, o 00:18 ] |
Tytuł: | Re: Tablica wartości funkcji utworzona preprocesorem |
Tamta stronka juz wygasła wiec pomyslalem ze moze dobrze bedzie zgrac z google webcache tametego generatora poki jeszcze jest dostepne. |
Autor: | rskup [ 21 maja 2014, o 09:53 ] |
Tytuł: | Re: Tablica wartości funkcji utworzona preprocesorem |
Witam, Właśnie natknąłem się na inny ciekawy sposób tworzenia tablicy z wartościami wyliczanymi przez preprocesor. Nie trzeba robić dodatkowego pliku do includowania a wykorzystać rekurencję: Kod: #define XTAB0(n) func(n), #define XTAB1(n) XTAB0(n) XTAB0(n+1) XTAB0(n+2) XTAB0(n+3) #define XTAB2(n) XTAB1(n) XTAB1(n+4) XTAB1(n+8) XTAB1(n+12) #define XTAB3(n) XTAB2(n) XTAB2(n+16) XTAB2(n+32) XTAB2(n+48) #define XTAB4(n) XTAB3(n) XTAB3(n+64) XTAB3(n+128) XTAB3(n+192) const uint8_t TABLE[] PROGMEM = { XTAB4(0) }; Dla powyższego kodu dostajemy w TABLE[] wartości będące wynikiem func(n) dla n od 0 do 255. Ale można to bardzo łatwo zmodyfikować na inne wielkości tablic oraz zmienić wartość początkową n na inną (zmiana w wywołaniu XTAB4(start_value)). -- Pozdrawiam, Robert |
Autor: | mirekk36 [ 21 maja 2014, o 10:04 ] |
Tytuł: | Re: Tablica wartości funkcji utworzona preprocesorem |
no fajne ciekawostki i smaczki ![]() |
Autor: | m@ciej [ 26 gru 2014, o 11:08 ] |
Tytuł: | Re: Tablica wartości funkcji utworzona preprocesorem |
A ja dłubałem program w Delphi, co mi zmienia format Excelowego słupka na format Pgm Space. Szlo to dość szybko, ale ta metoda jest niezła. Będę musiał ją przetrenować bo w perspektywie jest wpisanie okolo 30 tablic po 2048 elementów 16-bitowych by zrobić wavetable. Jak będzie zainteresowanie, udostępnię wspomniany programik. |
Strona 1 z 1 | Strefa czasowa: UTC + 1 |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |