Skocz do zawartości

sapero

Użytkownik
  • Postów

    2
  • Dołączył

  • Ostatnia wizyta

Osiągnięcia sapero

Newbie

Newbie (1/14)

0

Reputacja

  1. 2,2142807374883101672219837615212e+333060 to wynik z kalkulatora - u mnie liczył jakieś 20s i wywalił 2 okienka że to potrwa i czy kontynuować co mam zrobić z tymi kilkoma cyferkami? tyle wiem że wynik jest 2e333060 ale nam chodzi o prawdziwy wynik taki jeden serwer "liczy" 3 razy szybciej- ciekawe czy ma pośrednie wyniki czy jest taki krass. Porównałem się z wynikiem z serwera: identico :) niestety studenci zrobili bałagan na stronie i link jest bad; a jeśli ktoś chciałby sprawdzić swój wynik obliczeń to chętnie udostępnię albo program albo wynik
  2. witam właśnie dzisiaj przyspieszyłem programik do liczenia silnii (dobry dodatek w asmie) - i tak się składa, że operuje w BCD Zastosowałem tu szybkie mnożenie - dwie tablice - jedna to wynik i zarazem można, druga to taka podręczna pamięć dla szczątkowego wyniku mnożnik to liczba typu DWORD (4bajty). Wielkość obu tabel ogranicza tylko wydajność komputera: A i B to tabele, BC to mnożnik, tabela A to wynik i zarazem mnożna. Należy do niej wpisać liczbę którą się chce pomnożyć (oczywiście w BCD). Najmniej znaczące cyfry znajdują się na początku tabeli ( a[0] ) Tabela B powinna być wyzerowana przed mnożeniem CHAR a[0xFFFFF], b[0xFFFFF] /* 2097150 cyfr dla wyniku */'zerowanie tabelRtlZeroMemory(&a, 0xFFFFF)RtlZeroMemory(&b, 0xFFFFF)'mnożymy 40000 * 7a[0]=7UINT BC, LenA /* LenA to ilość bajtów wyniku */BC = 40000LenA = 1'start'NASM assembler IBasic PRO _asm MOV eax,[$BC] ;eax = 40000LoopDo: MOV ebx,eax AND ebx,1 JZ RLCA ; jump if BC & 1 = 0 DEC eax ; mul-- PUSH eax;*************************AddAtoB: MOV ecx,[LenA] ; Counter MOV edx,$b MOV ebx,$a CLC ; Clear Carry LaddAB: MOV al,[edx] ; Get 2 bytes from b[n] ADC al,[ebx] ; Add a[n] DAA ; BCD correction MOV [edx],al ; Store in b[n] INC edx INC ebx LOOP LaddAB ; 'next n' JNC Lrlcaexit INC dword[edx] ; if Carry then add one digit JMP Lrlcaexit;*************************RLCA: SHR eax,1 ; mul = mul >> 1 PUSH eax;************************* MOV ecx,[LenA] ; Counter MOV ebx,$a CLC ; Clear Carry Lrlca: MOV al,[ebx] ; Get 2 bytes from a[n] ADC al,al ; bytes *2 + Carry DAA ; BCD correction MOV [ebx],al ; Store in a[n] INC ebx ; n++ LOOP Lrlca ; 'next n' JNC Lrlcaexit INC dword[ebx] ; if Carry then add one digit INC dword[$LenA]; and inc number of digits;*************************Lrlcaexit: POP eax CMP eax,1 JA LoopDo ; until BC>1;*************************AddBtoA: MOV ecx,[LenA] ; Counter MOV edx,$a MOV ebx,$b CLC ; Clear Carry LaddBA: MOV al,[edx] ; Get 2 bytes from a[n] ADC al,[ebx] ; Add bytes from b[n] DAA ; BCD correction MOV [edx],al ; Store in a[n] INC edx ; n++ INC ebx LOOP LaddBA ; 'next n' JNC LaddBAexit INC dword[edx] ; if Carry then add one digit INC dword[$LenA]; and inc number of digitsLaddBAexit: _endasmJak to działa: jeśli BC jest parzyste : podziel BC przez 2 a wynik pomnóż przez 2 a jeśli BC nie jest parzyste : odejmij jeden od BC i dodaj wynik (tabela A) do liczby BCD w tabeli B powtarzaj od początku dopuki BC > 1 na końcu dodaj liczbę z tabeli B do liczby z tabeli A jak łatwo zauważyć dla mnożnika 40000 cała pętla wykona się 16 razy (40000 to 16 bitów) a zatem jest to (chyba) najszybszy algorytm mnożenia, urodzony w czasach rozkwitu zx spectrum 8) Liczbę cyfr wyniku obliczamy digits = (LenA * 2) - (a[LenA-1]<0x10)wynik można wyświetlić taksub PrintA INT x For x=LenA-1 to 0 step -1 Print Hex$(a[x]), /* dla delphii: IntToHex(a[x], 2) */ Next x ReturnEndsubkilka wyników obliczania silnii tym alborytmem na Athlonie 2800+ 1000! - 0.078s 2568 cyfr 10000! - 13s 35660 cyfr 50000! - 7min 213237 cyfr 75000! - 19min 333061 cyfr
×
×
  • Dodaj nową pozycję...