Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki



Teraz jest 28 mar 2024, o 21:21


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 4 ] 
Autor Wiadomość
PostNapisane: 24 kwi 2019, o 21:33 
Offline
Nowy

Dołączył(a): 26 sie 2018
Posty: 3
Pomógł: 0

Mam problem do rozwiązania. Potrzebuję w mojej aplikacji przemnożyć wartość z zakresu 0-4095 przez wartość zmiennoprzecinkową z zakresu 0-2,00 wprowadzaną przez użytkownika. Wymyśliłem sobie, że wartość zmiennoprzecinkową będę reprezentował za pomocą trzech zmiennych uint8_t odpowiadającym trzem cyfrom (setki, dziesiątki, jedności), następnie zsumuję cyfry, przemnożę przez wartość 0-4095, a następnie podzielę przez 100. Zmienna wynik jest typu uint16 i przechowuje wartość z ADC z zakresu 0-4095. Po przemnożeniu chciałbym aby zmienna wynik była nadal typu uint16.
Przykładowy kod:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Istotne jest dla mnie, żeby uzyskać możliwie najkrótszy czas mnożenia i dzielenia. Na ile da się ten przykład zoptymalizować? Jak na razie jestem daleki od założonych ram czasowych wykonywania tego fragmentu kodu. Te trzy linijki kodu wprowadzają ok 40 us opóźnienia. Natomiast zapasu na to mam ok 7 us. Procesor pracuje na 16 MHz.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 24 kwi 2019, o 22:04 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27212
Lokalizacja: Szczecin
Pomógł: 1041

sir_auron napisał(a):
bo bez tego miałem przepełnienie zmiennej przy mnożeniu przez >16, tak jakby iloczyn był uint16.

Bo pewnie nie słyszałeś o domyślnej promocji do INT w języku C

https://atnel.pl/domyslna-promocja-do-typu-int.html

jak to przeczytasz to zrozumiesz dlaczego w takich wypadkach jest wymagane jawne rzutowanie

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 25 kwi 2019, o 14:29 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 18 sie 2013
Posty: 50
Lokalizacja: Żary/Wrocław
Pomógł: 1

Nie używaj floatów :( To jest zło. Ostatnio czytam takiego chłopaka i on napisał fajny artykuł o floatach. CO prawda na STM32, ale float to float :D https://msalamon.pl/ile-kosztuje-uzywan ... -daje-fpu/



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 26 kwi 2019, o 18:41 
Offline
Użytkownik

Dołączył(a): 28 wrz 2016
Posty: 215
Pomógł: 14

Jak rozumiem zadanie polega na przemnożeniu liczby z zakresu 0-4095 (12 bit) przez współczynnik z zakresu 0-2,00 (dwie cyfry znaczące po przecinku), a wynik ma być liczba całkowitą z zakresu 0-8192 (13 bit). By się nie myliło liczba 0-4095 niech nazywa się pomiar, liczba 0-2,00 nazywa się współczynnik, a wynik ich mnożenia to wynik. I wynik ma być typu uint16.
Najpierw przedstawmy współczynnik w postaci liczby całkowitej 8 bit z zakresu 0-255. Zrobimy to po prostu mnożąc współczynnik przez 128 i pomijając część po przecinku. Uzyskujemy liczbę całkowitą typu uint8. Teraz wystarczy pomnożyć liczbę uint16 przez uint8, a wynik podzielić przez 128.
Dzielenie przez 128 to przesuniecie o 7 bitów w prawo. Więc 7 najmniej znaczących bitów wyniku zostanie zignorowane. Te 7 bitów to część ułamkowa wyniku, którą mamy zaokrąglić. Należałoby też dodać 1 na 7 bicie by zaokrąglanie było i w górę i w dół.
Ponieważ i tak pozbywamy się 7 bitów po mnożeniu w wyniku, to nie popełnimy dużego błędu gdy części z tych 7 bitów pozbędziemy się przed mnożeniem w pomiarze np 3 bity i współczynniku np 2bity. Wtedy mnożymy liczbę 10bit przez 6bit i uzyskujemy 16bit, która to mieści się w 16 bitach typu uint16. Pozbyliśmy się 3+2=5bitów pozostały jeszcze 2, których to pozbędziemy się już w wyniku. Taka byłaby moja idea rozwiązania tego problemu.
Alternatywnie można spróbować wykorzystać matematykę liczb stałoprzecinkowych, lub samemu napisać algorytm mnożenia, co wbrew pozorom nie jest takie trudne

_________________
de gustibus non est disputandum



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 4 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 8 gości


Nie możesz rozpoczynać nowych wątków
Nie możesz odpowiadać w wątkach
Nie możesz edytować swoich postów
Nie możesz usuwać swoich postów
Nie możesz dodawać załączników

Szukaj:
Skocz do:  
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO