40 bit Wurzel AVR ASM

Gast #2698994
Lesenswert?

Hallo Markus,
entschuldige, dass ich die Informationen vergessen habe.
Also:
-ATMEGA88PA
Format Radikand: 40bit Integer
Format Ergebniss: 20bit Integer, gerundet (ob auf oder ab ist ja egal)y

Ich hab mir schon die 32bit Wurzel Funktion hier im Wiki angeschaut. 
Allerdings weiß ich nicht, wie ich die "erweitern" kann.
Persönliche Seite #2699043
Lesenswert?

Sebi schrieb:

> Ich hab mir schon die 32bit Wurzel Funktion hier im Wiki angeschaut.
> Allerdings weiß ich nicht, wie ich die "erweitern" kann.

Anstatt 4-Byte Eingabe wird's eine 5-Byte Eingabe.
Anstatt 2-Byte Ausgabe wird's eine 3-Byte Ausgabe.

In einem ersten Schritt kannst du die hartcodierten Register zum 
bwesseren Überblick ersezten:
 
1
ldi   R19, 0xc0
2
clr   R18          ; rotation mask in R19:R18
3
ldi   R27, 0x40
4
sub   R26, R26     ; developing sqrt in R27:R26, C=0

wird dann zu
 
1
#define RES 26
2
#define MASK 18
3
#define BITS 40
4

5
; rotation mask in MASK
6
ldi   MASK+1, 3 << ((BITS-2) % 8)
7
clr   MASK
8

9
; expand sqrt in RES, C=0
10
ldi   RES+1, 1 << ((BITS/2-2) % 8)
11
sub   RES,   RES
12

13
...
14

15
#undef BITS
16
#undef MASK
17
#undef RES

In einem 2. Schritt erweiterst du dann die Arbeitsregister zur jeweils 
benötigten Bitbreite:
1
; rotation mask in MASK
2
ldi   MASK+2, 3 << ((BITS-2) % 8)
3
clr   MASK+1
4
clr   MASK

Die Shifts oben musst noch nachrechnen (Hausaufgabe).

hmmm. oder erweitern auf 6 Byte Radikant, die Routine setzt wohl voraus, 
daß der Radikant eine gerade Anzahl Bytes groß ist, d.h. das Erhebnis 
nicht 2.5 Bytes groß ist.
Gast #2700489
Lesenswert?

Verlfucht, ich krieg es nicht hin.
Andere Baustelle: Heron Verfahren.
Wie krieg ich das ohne die Division Xn/a hin? Division durch zwei ist ja 
kein Ding (shift) aber die andere Division bereit mir Kopfzerbrechen.
Gast #2700995
Lesenswert?

1
;  R18:R17:R16=SQRT(R6:R5:R4:R3:R2:R1)
2
SQRT48:
3
    ldi r21,0xc0 
4
    clr r20
5
    clr r19
6
    ldi   R18,0x40
7
        clr r17
8
    sub r16,r16
9
_sq48_1:    brcs  _sq48_2
10
    cp r4,r16
11
    cpc r5,r17
12
    cpc r6,r28
13
    brcs  _sq48_3
14
_sq48_2:    sub   R4,R16
15
    sbc r5,r17
16
    sbc r6,r18
17
    or r16,r19
18
    or r17,r20
19
    or r18,r21
20
_sq48_3:    lsr   R21
21
    ror r20
22
    ror r19
23
    eor r18,r21
24
    eor r17,r20
25
    eor r16,r19
26
    rol r1
27
    rol r2
28
    rol r3
29
    rol r4
30
    rol r5
31
    rol r6
32
    sbrs r1,0
33
    rjmp  _sq48_1 
34

35
    brcs  _sq48_4
36
    lsl   R3
37
    cpc   R16,R4
38
    cpc   r17,r5
39
    cpc    r18,r6
40
_sq48_4:    adc   R16,r21
41
ret

das ist der klägliche Versuch.
#2701099
Lesenswert?

Hallo,

als ich
 sqrt(1+x) = 1 + x/2 + eps  heute gesehen habe, fiel mir spotan soetwas 
ein:
Falls die Zahl kleiner 32 -Bit ist einfach 32 Bit Rechnung.-> trivial.
Falls die Zahl >=2^32 ist dann die Zahl aufspalten
N = K*256 + C mit K = oberen 32 Bits und C = N mod 255 also die unter 8 
Bit

Wurzel(N)=Wurzel(K*256 + C)
erweitert mit 1=Wurzel(K*256)/Wurzel(K*256)
=Wurzel(K*256)*Wurzel( (K*256)/(K*256) + C/(K*256))

= Wurzel(K*256)*Wurzel( 1+ C/(K*256))
x = c/(256*K) | irgenwas kleiner 2^-24 < 1e-7
= 16*Wurzel(K) + (16*Wurzel(K)* C/(256*K)/2
= 16*Wurzel(K) // + C/(16*Wurzel(K))/2 < 1/512 )
Dummerweise ist Wurzel(K) nur eine 16 Bit Integerzahl. :-(
Wenn man eine Wurzelfunktion hätte, die 32 Bit integer ins 16.8 Format 
umrechnen würde, hätte man ein Chance.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren