Dzielenie z AVR

Mar 31, 2006 8 Replies

Witam Mam problem z obliczeniem punktu na prostej w asemblerze, a w zasadzie z operacja dzielenia w asemblerze. Potrzebna jest mi procedura dzielaca dwie liczby 16-nasto bitowe w asemblerze AVR. Z tego co sie zorientowalem w atmega8 nie ma zadnyc rozkazow dzielenia Znalazlem na stronie atmel'a procedure dzielenia,ale w wyniku otrzymuje liczbe calkowita i reszte - dwie oddzielne liczby , a mi potrzebna jest wartosc typu 0,xxxx zwlaszcza ze wyniki beda mialy wartosci 1>x>0



Jesli ktos ma taka procedure, wie gdzie ja znalezc albo ewentualnie pomysl jak to zrobic, to bede wdzieczny za informacje Pozdrawiam i z gory dziekuje TsfJacek


TsfJacek napisał(a):

I pewnie zawsze taką dostaniesz. Sam to musisz odpowiednio interpretować.

Witam,

Rozumiem, że chodzi Ci o wynik w postaci zmiennoprzecinkowej?

No to w CPU bez dedykowanego FPU pozostaje albo napisać jego emulację/odpowiednią bibliotekę albo poświęcić trochę niższych bitów na część po przecinku. (w twoim wypadku dla 1>x>0 akurat wszystkie tak, że 0xFFFF = 1 a 0x0000 byłoby 0)

Pozdrawiam,

Radek

Musze w asemblerze dla atmega8 wyliczyc z takiego rownania y y={[(wsk1-wsk2)*255+offset1-offset2]/(op1-op2)}*{'(wsk1-wsk2)*255+offset-offset2}+op2

i problem jest z dzieleniem [(wsk1-wsk2)*255+offset1-offset2]/(op1-op2)

Moglbys cos wiecej napisac o tej czesci po przecinku - jak to ma dzialac., bo pozniej czeka mnie mnozenie i nie wiem jakby ewentualnie mialo to wygladac w wersji liczba +reszta tsfjacek

U¿ytkownik "Radek" snipped-for-privacy@mitsoft.com.pl> napisa³ w wiadomo¶ci news:e0j8jh$s92$ snipped-for-privacy@nemesis.news.tpi.pl...

"TsfJacek" snipped-for-privacy@op.pl wrote in message news:e0j6ts$kha$ snipped-for-privacy@news.lublin.pl... ciach proponuje poszukac matrialow dotyczacych arytmetyki maszyn binarnych - znajdziesz je bez klopotu - ostatnio (wczoraj czy przedwczoraj) byl watek o tym jak liczy kalkulator...

Odpisuj pod postem. Masz dwie mozliwosci - implementowac arytmetyke zmiennopozycyjna, dlugie i upierdliwe. Albo wykorzystac arytmetyke stalopozycyjna. Czyli zakladasz, ze np. kazda liczba ma stala ilosc cyfr po przecinku. W tym wypadku wykorzystujesz zwykle obliczenia na liczbach calkowitych pamietajac tylko aby po operacji odpowiednio przeskalowac liczbe. Pomysl do kitu jesli poszczegolne zmienne zawieraja diametralnie odbiegajace od siebie liczby i nie da sie ich pogrupowac na czynniki w miare do siebie podobne jesli chodzi o zakres.

Witam,

Takich trików używałem na ARM ale reguła będzie taka sama na każdym innym procesorze.

Powiedzmy, że używam 16 bitowych słów ale chcę np. zrobić iloczyn liczb A = 12.321 i B = 0.4. Zakładam, że wystarczy mi tylko 8 bitów precyzji dla części po przecinku więc 16 bitów mam coś takiego: 8:8.

Reprezentacja A i B w takim formacie wygląda (A << 8) i (B << 8) czyli 102 i 3154. Mnożę te liczby normalnie i uzyskuje 321708.

Teraz pierwsze 16 bitów zawiera część po przecinku (piszę tutaj w Pythonie): (321708 & 0xFFFF)/float(0xFFFF) = 0.91 (w przybliżeniu)

Pozostałe bity zawierają część stałoprzecinkową: (321708 >> 16) = 4

W wyniku efektywnie 4.91 kiedy 12.321 * 0.4 = 4.9283999999999999.

Im więcej bitów przeznaczy się na część zmiennoprzecinkową tym błąd obliczenia będzie mniejszy. To będzie zawsze kompromis nawet na 32 bitowym ARM a tym bardziej będzie na 8 bitowym procku. Jednak szybciej się nie da pracować na ułamkach na maszynach bez FPU.

Ale mogą się pojawić kłopoty z zakresem liczb więc to rozwiązanie nie jest idealne. Wtedy jednak pozostanie tylko implementacja kompletnej biblioteki zmiennoprzecinkowej.

Pozdrawiam,

Radek

mam procedurę w IEEE 754 na pica bo prace pisałem na tym procku. dzielenie zmienno przecinkowe można łatwo zrobić dzieląc 32bity na 16. W ten sposób masz od razu wartośc po przecinku bez żadnych manewrów tylko musisz wiedzieć gdzie przecinek czyli po 16 bitach wyniku zawierających całość. Czyli do starszych dwóch bajtów ładujesz liczbę, młodsze 2 są zero, a dzielnik normalnie. Przykłady dzielenia ogólnie są na

formatting link
i jak załapiesz o co chodzi na podstawie dzielenia 8/8 to już jesteś w domu, oczywiście pamiętając o korekcie przepełnień wynikających z dodawań i odejmowań.

No to przemnó¿ dzieln± przez potêgê 10 (albo 2, zale¿y w jakim zapisie jest to 0,xxxx). Wynik wyjdzie ca³kowity.

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required