Selam,
CCS forumlarını gezerken çok güzel bir kod gözüme çarptı. 32 bit karekök alma kodu :
long uisqrt32(int32 r)
{
int32 t,b,c=0;
for (b=0x10000000;b!=0;b>>=2) {
t = c + b;
c >>= 1;
if (t <= r) {
r -= t;
c += b;
}
}
return(c);
}
İşte C böyle kullanılır ;)
Analyzer
CCS ARM7'ler için de mi derleyici çıkartmış? Yoksa bu kod 8 bitlik picler için mi?
16 serisi Piclerde floating point bölme işlemi dokuzyüz küsür komut adımını bulabiliyor. Hele karekök için nasıl olur Allah bilir.
18 serisi için bu kadar kod adımı bulunuyor.
.................... long uisqrt32(int32 r)
.................... {
.................... int32 t,b,c=0;
0004: CLRF 12
0006: CLRF 13
0008: CLRF 14
000A: CLRF 15
....................
.................... for (b=0x10000000;b!=0;b>>=2) {
000C: MOVLW 10
000E: MOVWF 11
0010: CLRF 10
0012: CLRF 0F
0014: CLRF 0E
0016: MOVF 0E,F
0018: BNZ 0026
001A: MOVF 0F,F
001C: BNZ 0026
001E: MOVF 10,F
0020: BNZ 0026
0022: MOVF 11,F
0024: BZ 009C
.................... t = c + b;
0026: MOVF 0E,W
0028: ADDWF 12,W
002A: MOVWF 0A
002C: MOVF 0F,W
002E: ADDWFC 13,W
0030: MOVWF 0B
0032: MOVF 10,W
0034: ADDWFC 14,W
0036: MOVWF 0C
0038: MOVF 11,W
003A: ADDWFC 15,W
003C: MOVWF 0D
.................... c >>= 1;
003E: BCF FD8.0
0040: RRCF 15,F
0042: RRCF 14,F
0044: RRCF 13,F
0046: RRCF 12,F
.................... if (t <= r) {
0048: MOVF 0D,W
004A: SUBWF 09,W
004C: BNC 0086
004E: BNZ 0066
0050: MOVF 0C,W
0052: SUBWF 08,W
0054: BNC 0086
0056: BNZ 0066
0058: MOVF 0B,W
005A: SUBWF 07,W
005C: BNC 0086
005E: BNZ 0066
0060: MOVF 0A,W
0062: SUBWF 06,W
0064: BNC 0086
.................... r -= t;
0066: MOVF 0A,W
0068: SUBWF 06,F
006A: MOVF 0B,W
006C: SUBWFB 07,F
006E: MOVF 0C,W
0070: SUBWFB 08,F
0072: MOVF 0D,W
0074: SUBWFB 09,F
.................... c += b;
0076: MOVF 0E,W
0078: ADDWF 12,F
007A: MOVF 0F,W
007C: ADDWFC 13,F
007E: MOVF 10,W
0080: ADDWFC 14,F
0082: MOVF 11,W
0084: ADDWFC 15,F
.................... }
.................... }
0086: RRCF 11,F
0088: RRCF 10,F
008A: RRCF 0F,F
008C: RRCF 0E,F
008E: RRCF 11,F
0090: RRCF 10,F
0092: RRCF 0F,F
0094: RRCF 0E,F
0096: MOVLW 3F
0098: ANDWF 11,F
009A: BRA 0016
.................... return(c);
009C: MOVFF 12,01
00A0: MOVFF 13,02
.................... }
00A4: GOTO 0106 (RETURN)
Alıntı yapılan: "Ziya"CCS ARM7'ler için de mi derleyici çıkartmış? Yoksa bu kod 8 bitlik picler için mi?
Hayır, sadece ccs forumunda gördüğüm için söyledim. Herhangi bir C derleyicisinde herhangi bir mcu'ya uyarlanabilir.
Analyzer
Başlığı --ARM7 Mikrodenetleyici-- altına açmışsınız. O nedenle sormuştum.
Kod 32bit ya.. Ayıp olurdu pic bölümüne açsaydım :D
Analyzer
Alıntı Yap18 serisi için bu kadar kod adımı bulunuyor.
Flashta bu kadar yer tutuyor demek daha dogru olur.
Bu fonksyonu çalistirinca koddan daha fazla adim çalisiyor.
for (b=0x10000000;b!=0;b>>=2)
Demek döngünün 14 kez tekrarlanacagini gösterir(2^29)/(2^2)
14 * 0x009A-0x000C = 14 * 142 = 1988 adim
Ayni yöntemle bir float sayisinin kare kökü hesaplanirsa acaba ne kadar süre tutar? Belki float için baska bir yöntem kullaniliyordur.
Alıntı yapılan: "picusta"Alıntı Yap
for (b=0x10000000;b!=0;b>>=2)
Demek döngünün 14 kez tekrarlanacagini gösterir(2^29)/(2^2)
Bu döngüyü anlamadım.b sayısı her seferinde 2 sağa kaydırılmıyor mu?
32bit sayı: 00010000 00000000 00000000 00000000 her defasında 2 sağa kayarsa 15 döngü etmiyor mu?
int saga kaydirilinca 2 ile bölme oluyor. 2 kere kaydirilinca 4'le bölmeye denk geliyor. b sayisi basta 2^28. Bu yüzden float'la ayni seyi yapmaya kalkarsak Epey bi sürer.
Alıntı yapılan: "Ziya"32bit sayı: 00010000 00000000 00000000 00000000 her defasında 2 sağa kayarsa 15 döngü etmiyor mu?
Evet hocam doğru.Bir an 0x şeklindeki gösterimi binary olarak düşünmüşüm.