Skocz do zawartości
danrok

[assembler] Problem Z Dzieleniem 16bitowym

Rekomendowane odpowiedzi

Hej,

tym razem mam problem z dzieleniem. Czy ktoś mógłby przybliżyć tylko algorytm,

który łatwo jest zapisać w asseblerze? ;) Chciałbym to zrobić sam, ale jakoś brakuje

mi dobrego algorytmu ;) Patrzyłem też do

noty katalogowej

czy da się to jednak zrobić może prościej?

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Gość <account_deleted>

Jeśli piszesz program obliczeniowy, to nie najlepszym pomysłem jest używanie "naturalnego" formatu integer. Algorytm ze strony Atmela jest cieniuutki - co niby masz zrobić z resztą z dzielenia? Przecierz kalkulator ma pokazać np. 5/4 = 1.25 a nie "1 reszta 1". I tu zaczynają się schody :) Jakbyś pogrzebał na necie to znajdziesz algorytmy oparte o fmul, ale też nie jest to mistrzostwo świata - śmieszna dokładność - ale może Tobie to wystarczy? Z kolei do obsługi liczb w formacie floating point ten procek jest poprostu za słaby.

 

Patentem jest stworzenie swojego formatu zapisu liczb i częściowe zastąpienie dzielenia mnożeniem, np. :

z=x/y = x*(1/y).

Co to daje: mnożenie już masz - prawie najszybsze jakie da się zrobić ;), a wykorzystując tą metodę możesz mnożyć liczby o dowolnej długości, f.e. 128bit. Z kolei algorytm dzielenia 1/y jest znacznie prostszy i szybszy niż x/y

Format liczb może być np. taki:

0b_0000000s_iiiiiiii_iiiiiiii_ffffffff_ffffffff

- jest to format stałoprzecinkowy (fixed point) - bajt znaku+16bit integer + 16bit fraction (część ułamkowa), albo jeszcze lepiej taki:

0b_sddddddd__iiiiiiii_iiiiiiii_ffffffff_ffffffff, d-położenie przecinka (decimal point)

Można też skorzystać ze starego jak informatyka patentu:

z=(x*0x10000)/y - co daje znacznie większą dynamikę/dokładność obliczeń

 

Pytanie brzmi: co właściwie chcesz liczyć - czy to ma być tylko experymet w symulatorze, czy coś poważniejszego? Jakiej dokładności potrzebujesz?

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Gość <account_deleted>

Nie lubisz wyzwań? :rolleyes:

 

UDIV_A_B:;unsigned 16/16bit division;A = R21:R20;B = R15:R14;A/B = R19:R18:R17:R16;temp = R23:R22;output format: 0x0000.0000 (integer.fraction);0/0 = 0;(A<>0)/0 = 0xFFFF.FFFF		ldi	r24,32;bit position counter		clr	r16;clear result		clr	r17		movw	r19:r18,r17:r16;fast clear		movw	r23:r22,r17:r16;precharge:		lsl	r20		rol	r21		rol	r22;r23:r22 = temp remainder from divsion + carry;processingLOOP32:				cp	r14,r22;check if A shifted left by n-bits is greater		cpc	r15,r23;than B value		brcc	LP32_SKP1		sbr	r16,0x01;current position bit value = 1		sub	r22,r14;temp remainder from division		sbc	r23,r15LP32_SKP1:			dec	r24		breq	AB_DONE;LSB processed, end				lsl	r20;in-shift Carry from current MSB of A (0 after 16 turns)		rol	r21		rol	r22		rol	r23		lsl	r16;make place for next bit in result		rol	r17		rol	r18		rol	r19		rjmp	LOOP32;max 32 jumps per call;processing time: 550clk avgAB_DONE:		ret
Żeby było ciekawiej: sam wymyśl jak pozbyć się lub wykorzystać część ułamkową ;)

 

1/16bit jest grubo ponad 2x szybsze ;)

 

;edit: czcionkę zmniejszyłem, bo mi post cały ekran zajmował ...

 

;edit2: danrok, sorry ale nie przeczytałem twojego posta ze zrozumieniem :oops: - miał być sam algorytm....

Ten algorytm to dosłownie pisemne dzielenie liczb dziesiętnych (binarnych) - takie jakiego uczą w szkole podstawowej :)

Edytowane przez tomazzi

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Gość <account_deleted>

To jest wersja zoptymalizowana pod kątem zapotrzebowania na pamięć - powstała dla Tiny13. Można też napisać wersję nastawioną na szybkość - myślę że da się zejść gdzieś do poziomu 300clk (średnio) - np. poprzez sprawdzanie ile bitów zajmuje zmienna A i rozpoczynanie liczenia z pominięciem początkowych zer ;)

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

moze mu zalezy na szybkosci ? albo objetosci kodu ? , jego kalkulator w asm'ie pobije twoj w c pod wzgledem wydajnosci i objetosci, ale bedize go dluzej pisac ;]

Ależ oczywiście. Przecież lepiej mieć o 1% szybszy program, zajmujący kilkadziesiąt kilo pamięci mniej i pisać go tydzień... :lol:

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Ok, chcę go napisać w Assemblerze. Wiem, że napisać to w C 15 minut, ale chcę poznać zasadę działania dokładną i ... lubię wyzwania po prostu. Decyzja o pisaniu w Asseblerze wyszła ode mnie i nie ma żadnych powodów ku temu - po prostu kaprys i chęć nauki czegoś nowego.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Gość <account_deleted>

Ależ oczywiście. Przecież lepiej mieć o 1% szybszy program, zajmujący kilkadziesiąt kilo pamięci mniej i pisać go tydzień... :lol:

Nie o 1% tylko o 100/300/500% ++ bo takie są róznice między między dobrze napisanym asm i C. Poza tym C nie nadaje się do takich małych procków ze względu na ograniczeną ilość RAMu i wydajność CPU, a już obliczenia szczególnie.

 

Tydzień pisania? chyba sobie jaja robisz - jak ktoś zna asm, to pisze tak samo szybko /jeśli nie szybciej/ jak w C. Jak ktoś nie zna C to taki kalkulator też będzie pisał tydzień :lol:

 

Poza tym twoje uwagi nic nie wnoszą do tematu.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Gość <account_deleted>

Program w asm:

 

GET_KEY PortB

TRANSLATE_KEYCODE

SEND_KCODE_LCD

 

Wiesz co to code snippets /macra? Skończ już robić z siebie idiotę i wydłużać swój głupi offtop.

 

/edit: widzę, że ktoś pozamiatał w temacie...

Edytowane przez tomazzi

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Gość <account_deleted>

ma mniej cykli, bo około 300 max;)

tak, ale nie liczy ułamków ;)

 

pochwalisz się źródełkiem?

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Dołącz do dyskusji

Możesz dodać zawartość już teraz a zarejestrować się później. Jeśli posiadasz już konto, zaloguj się aby dodać zawartość za jego pomocą.

Gość
Dodaj odpowiedź do tematu...

×   Wklejono zawartość z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Odnośnik został automatycznie osadzony.   Przywróć wyświetlanie jako odnośnik

×   Przywrócono poprzednią zawartość.   Wyczyść edytor

×   Nie możesz bezpośrednio wkleić grafiki. Dodaj lub załącz grafiki z adresu URL.

Ładowanie


×
×
  • Dodaj nową pozycję...