Avatar billede oleoleo1 Nybegynder
18. marts 2009 - 12:59 Der er 14 kommentarer og
1 løsning

Speciel hex konvertering..

Hej Eksperter.

Er der nogen som har en algoritme (helst bare generel, ellers assembly) til at konvertere et hex tal til en hex-repræsentation af det decimale tal. Altså

0x10 -> 0x16    (i dec er det 16->22)
0x47-> 0x71      (i dec er det 71->113)
Avatar billede thov Forsker
18. marts 2009 - 13:40 #1
Talsystemer er ikke så svære - tag f.eks. tallet 1111:

binært: 8+4+2+1 = 15 (decimalt)
oktalt: 512+64+8+1 = 585
dec.  : 1000+100+10+1 = 1111
hex.  : 4096+256+16+1 = 4369

Det som forvirrer, er 'manglen' på symboler, når grundtallet kommer over 10.
Vi vil helst bruge dem vi kender (tallene fra 0..9), men så er vi på den, for de duer ikke fra 10..15.
Enten skulle man opfinde helt nye symboler, eller fortsætte med en, i forvejen, kendt 'remse', og her er bogataverne A..F idelle.
Avatar billede arne_v Ekspert
18. marts 2009 - 13:58 #2
Kode (Java) som viser konverteringen:

public class HexFun {
    private final static String DIGITS = "0123456789ABCDEF";
    private static int fromRadix(String s, int radix) {
        int res = 0;
        for(int i = 0; i < s.length(); i++) {
            res = radix * res + DIGITS.indexOf(s.charAt(i));
        }
        return res;
    }
    private static String toRadix(int v, int radix) {
        String res = "";
        int tmp = v;
        while(tmp > 0) {
            res = DIGITS.charAt(tmp % radix) + res;
            tmp /= radix;
        }
        return res;
    }
    private static String weirdConversion(String s) {
        return "0x" + toRadix(fromRadix(s.substring(2), 16), 10);
    }
    public static void main(String[] args) {
        System.out.println(weirdConversion("0x10"));
        System.out.println(weirdConversion("0x47"));
    }
}

Det boer kunne implementeres i ethvert programmerings sprog.

Men giver det mening ????

Din algoritme er ikke veldefineret for hex tal som indeholder A-F !
Avatar billede oleoleo1 Nybegynder
18. marts 2009 - 14:29 #3
thov: Jeg har ikke svært ved talsystemerne, jeg skal bruge konverteringen til nogle LEDdrivers.

arne_v: 

Jeg prøver lige at se om jeg kan decifrere din algoritme, den ser ud til at virke.

>Din algoritme er ikke veldefineret for hex tal som indeholder A-F !< ??

0xAE -> 0x174    (174->372), jeg skal dog kun bruge tallene fra 00-99 by the way..
Avatar billede arne_v Ekspert
18. marts 2009 - 15:30 #4
Du har ret - det boer virke - mit program spytrter da ogsaa 0x174 ud for 0xAE.
Avatar billede oleoleo1 Nybegynder
18. marts 2009 - 16:41 #5
arne_v: jeg synes umiddelbart den er svær at oversætte, da jeg ikke har nogle strings i assembler. Jeg kan ikke se andet end at jeg bliver nødt til at have den numeriske repræsentation ud i den anden ende, før det virker.  Det her var mit udkast:

    mov tmp1, segDisp ; f.eks. = 0xAE
    mov tmp2, segDisp  ; = AE
    ldi tmp3, 16                ; = 16 
    swap tmp1 ; byt nibbles rundt = 0xEA
    andi tmp1, 0b00001111 ; highNibble = A
    andi tmp2, 0b00001111 ; lowNibble  = E
    mul tmp1, tmp3 ; HighNibble * 16
    add tmp1, tmp2 ; (16 * HighNibble) + lowNibble
    mov segDisp, tmp1 ; updater

Jeg får ganske vist også 174 ud, men det er værdien 174 = 0xAE, og så er jeg jo lige vidt!

Det er AVR assembler jeg roder med, hvis der er nogen som har forstand på det(?), det kunne jo være der var en genvej (guess not), ellers må der være en måde at regne det ud på.
Avatar billede arne_v Ekspert
18. marts 2009 - 17:02 #6
Du har ikke strings, men du kan lave et array af bytes med de 16 ASCII vaerdier.

charAt er et simpelt opslag.

indexOf kraever en loekke.

Jeg kan godt lave koden i VAX assembler hvis du vil. Jeg kan ikke klare AVR assembler.
Avatar billede oleoleo1 Nybegynder
18. marts 2009 - 21:26 #7
arne_v:
Pseudo assembler vil formentlig være godt nok, så VAX assembler er sikkert fint (selvom jeg ikke ved hvordan det ser ud). Jeg kan godt finde ud af at lave et stort lookuptable med 0x00-0x99 som den kan slå op i, men det er ikke super elegant, så hvis du kan trylle et eksempel op ad baglommen skal du endelig ikke holde dig tilbage :).
Avatar billede arne_v Ekspert
19. marts 2009 - 03:16 #8
Jeg arbejder på sagen.

Men jeg blev ikke færdig i aften.
Avatar billede oleoleo1 Nybegynder
19. marts 2009 - 06:06 #9
arne_v:

Efter at have sovet på det, er det gået op mig at idéen med ét stort looktable, som måske ikke ser pænt ud i koden til gengæld må være noget af det hurtigste for processoren.
Således:

index  val
0x00  0x00
  ...      ....
  ...      ...
0x09  0x09
0xA0  0x10
0xA1  0x11

etc.. op til 99..

Hvis du har en smartere løsning, paste den endelig. Men lad være med at bruge dage på det :)
Avatar billede arne_v Ekspert
20. marts 2009 - 03:32 #10
Nu var det kun lookup table for de 16 tegn.

Men jeg endte med at spare dem og i.s.f. at bruge +-48 og +-7 hvis hex ciffer.

Koden kom til at se ud som:

        .title  hexfun
        $SSDEF
        .psect  $PDATA quad,pic,con,lcl,shr,noexe,nowrt
input1: .ascid  "0x10"
input2: .ascid  "0x47"
input3: .ascid  "0xAE"
prefix: .ascii  "0x"
        .psect  $LOCAL quad,pic,con,lcl,noshr,noexe,wrt
cvtval: .ascid  "          "
        .psect  $CODE quad,pic,con,lcl,shr,exe,nowrt
        .entry  fromradix,^m<r2,r3,r4,r5>
        movl    4(ap),r1
        movzwl  (r1),r2                ; string length
        subl2  #2,r2
        movl    4(r1),r3                ; string address
        addl2  #2,r3
        movl    8(ap),r4                ; radix
        clrl    r0                      ; result
100$:  tstl    r2
        bleq    200$
        mull2  r4,r0
        movzbl  (r3),r5
        subl2  #48,r5
        cmpl    r5,#10
        blss    150$
        subl2  #7,r5
150$:  addl2  r5,r0
        incl    r3
        decl    r2
        brb    100$
200$:  ret
        .entry  toradix,^m<r2,r3,r4,r5>
        movl    8(ap),r1                ; value
        movl    12(ap),r2              ; radix
        movl    4(ap),r3
        movl    4(r3),r3
        addl2  #9,r3                  ; result
300$:  tstl    r1
        bleq    400$
        divl3  r2,r1,r4
        mull3  r2,r4,r5
        subl3  r5,r1,r5
        addl2  #48,r5
        cmpl    r5,#57
        blss    350$
        subl2  #7,r5
350$:  movb    r5,(r3)
        movl    r4,r1
        decl    r3
        brb    300$
400$:  decl    r3
        movc3  #2,prefix,(r3)
        ret
        .entry  cvt,^m<>
        pushl  #16
        pushl  4(ap)
        calls  #2,fromradix
        pushl  #10
        pushl  r0
        pushab  cvtval
        calls  #3,toradix
        ret
        .entry  main,^m<>
        pushab  input1
        calls  #1,cvt
        pushab  cvtval
        calls  #1,G^LIB$PUT_OUTPUT
        pushab  input2
        calls  #1,cvt
        pushab  cvtval
        calls  #1,G^LIB$PUT_OUTPUT
        pushab  input3
        calls  #1,cvt
        pushab  cvtval
        calls  #1,G^LIB$PUT_OUTPUT
        movl    #SS$_NORMAL,r0
        ret
        .end    main
Avatar billede oleoleo1 Nybegynder
20. marts 2009 - 06:15 #11
arne_v:

Tak for det store arbejde!
Du har altså sparet noget flashram, men til gengæld tager det 3 gange så mange cycles at udregne, som hvis man bare slår op i et lookuptable.
I mit tilfælde er jeg lidt i tvivl, om din løsning er den bedste, men man kan i hvertfald sige det på denne måde: Hvis det nogensinde skal udbygges drastisk/eller i et lignende større projekt, vil din metode klart være at foretrække, i stedet for at have et lookuptable med eks. i million indexes.
Under alle omstændigheder vil jeg gerne give dig points'ne da du har løst opgaven, og lige meget om jeg gør det på denne måde eller med et stort loouptable, kan jeg sagtens forestille mig at der er nogen som bliver glade for din kode (måske ovenikøbet mig selv på et andet tidspunkt :)
Avatar billede arne_v Ekspert
21. marts 2009 - 02:58 #12
jeg smider et svar
Avatar billede arne_v Ekspert
21. marts 2009 - 02:59 #13
Jef fandt iøvrigt ud af at min Macro-32 var blevet lidt rusten. Jeg har ikke brugt det siden første halvdel af 90'erne.
Avatar billede oleoleo1 Nybegynder
21. marts 2009 - 08:14 #14
Hehe, så fik du også opfrisket det!
Avatar billede oleoleo1 Nybegynder
21. marts 2009 - 20:23 #15
Lige for en god ordens skyld. Her er løsningen med et lookuptable:

UPDATE7SEG:

    mov tmp1, segDisp
    ldi ZH,HIGH(segTrans *2)
    ldi ZL, LOW(segTrans *2) ; *2 så lsb = 0: read low Byte
    add ZL, tmp1
    lpm
    mov segDisp, r0
    out PORTA, segDisp
    ret

segTrans:

.db 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09
.db 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19
.db 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29
.db 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39
.db 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49
.db 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59
.db 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69
.db 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79
.db 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89
.db 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester