Zahl in String umwandeln

  • Hexworx schrieb:


    Eigentlich immer 0-9 in einzelne Bytes. Einfacher geht's ja nicht. Wenn die Scores o. ä. direkt als Chars geprinted werden sollen ginge das natürlich. Ist aber ja auch nicht die Regel.

    Versteh ich jetzt nicht.
    Mitwäre das nicht passiert! :prof:
    :syshack: Meine 3D-Drucker Teile auf thingiverse.com/oobdoo/designs :strom:
    Sammlung | 102 Bücher bzw. 28.009 Buchseiten mit Z80/8080/8085 Power
  • Acorn schrieb:

    Er hat sich ungenau ausgedrückt, er meinte für jede Ziffer ein Byte und dafür braucht man zehn Chars für die darzustellen.

    Ok. Und wenn man das so macht, wie rechnest dann was hinzu?

    Nachtrag:
    Hab gerade festgestellt, das bei meiner Methode keine Null übergeben werden darf. :(
    Dann stürzt das Programm ab, wenn ich die führenden Nullen wegmache. Da muß also zusätzlich noch ne Abfrage mit rein.
    Mitwäre das nicht passiert! :prof:
    :syshack: Meine 3D-Drucker Teile auf thingiverse.com/oobdoo/designs :strom:
    Sammlung | 102 Bücher bzw. 28.009 Buchseiten mit Z80/8080/8085 Power
  • oobdoo schrieb:

    Hab gerade festgestellt, das bei meiner Methode keine Null übergeben werden darf. :(
    Dann stürzt das Programm ab, wenn ich die führenden Nullen wegmache. Da muß also zusätzlich noch ne Abfrage mit rein.
    Es könnte sein, daß Du eine Stelle zuviel untersuchst. Tausch doch mal

    Quellcode

    1. ld b, 5
    gegen

    Quellcode

    1. ld b, 4
    aus und kopiere den String nicht um, sondern übergib einfach die verschobene Stringadresse an die Ausgaberoutine.
    Die Addition bei Ziffern funktioniert ungefähr so:

    Brainfuck-Quellcode

    1. ld b, 5
    2. ld ix, spieler_1_punkte
    3. call einer_addieren
    4. ...
    5. spieler_1_punkte:
    6. .byte ' ' ; Zehntausender
    7. .byte ' ' ; Tausender
    8. .byte ' ' ; Hunderter
    9. .byte ' ' ; Zehner
    10. .byte '0' ; Einer
    11. ;----------------------------------------
    12. ; einer_addieren
    13. ;
    14. ; B = Additionswert
    15. ; IX = Zeiger auf Spielerpunkte
    16. ;
    17. ;----------------------------------------
    18. einer_addieren:
    19. ld a, (ix + 4)
    20. add b
    21. call .test
    22. ld (ix + 4), a
    23. ret C
    24. ld a, (ix + 3)
    25. call .inc
    26. ld (ix + 3), a
    27. ret C
    28. ld a, (ix + 2)
    29. call .inc
    30. ld (ix + 2), a
    31. ret C
    32. ld a, (ix + 1)
    33. call .inc
    34. ld (ix + 1), a
    35. ret C
    36. ld a, (ix + 0)
    37. call .inc
    38. ld (ix + 0), a
    39. ret C
    40. ld a, '9' ; Überlauf im Punktezähler
    41. ld (ix + 0), a
    42. ld (ix + 1), a
    43. ld (ix + 2), a
    44. ld (ix + 3), a
    45. ld (ix + 4), a
    46. ret
    47. .inc: inc a
    48. .test: cp ' ' + 2 ; vorher Leerzeichen?
    49. jr C, .eins
    50. cp '9' + 1
    51. ret C
    52. sub 10 ; erniedrige um 10 und lösche Carry als Zeichen für Überlauf
    53. ret
    54. .eins: ld a, '1'
    55. ret
    Alles anzeigen
    Bei dieser Methode kann man beliebig viele Stellen verwenden und damit auch einfach Zahlen erzeugen > 65535.
  • Registerinhalte sind nicht "hex", dammich!

    TheRyk schrieb:

    Spannender ist HEX nach DEC und umgekehrt, aber dafür findet man Schnipsel auf Codebase :)

    Hexworx schrieb:

    Die Ausgabe HEX in DEC ist zum Glück ja auch eher die Ausnahme.


    Wenn sogar Graham diesen Fehler macht, ist vermutlich eh Hopfen und Malz verloren, aber ich sags trotzdem: Die verlinkte Routine konvertiert nicht von hexadezimal zu dezimal, sondern von Integer zu dezimal.
    Mit "Hexadezimal" ist eine Zahlendarstellung mit sechzehn verschiedenen Ziffern gemeint. Aus naheliegenden Gründen werden Register- und Speicherinhalte von Rechnern, deren Wortbreite durch acht teilbar ist, gern in diesem Format angezeigt. Aber solange keine Anzeige erfolgt, sind die Inhalte weder hexadezimal noch dezimal noch sexagesimal, echt jetz.
    Yes, I'm the guy responsible for the ACME cross assembler
  • oobdoo schrieb:

    Zitat von »Hexworx«

    Eigentlich immer 0-9 in einzelne Bytes. Einfacher geht's ja nicht. Wenn die Scores o. ä. direkt als Chars geprinted werden sollen ginge das natürlich. Ist aber ja auch nicht die Regel.

    Versteh ich jetzt nicht.

    Das war ja bezogen auf ACE's Aussage, direkt in PETSCII zu zählen, also von #$30 bis #$39. Macht natürlich nur Sinn, wenn man den Score auch als 8x8 Chars darstellen will. Wenn ich da Tiles oder Sprites habe, würde ich wohl eher von #$00 bis #$09 zählen (oder vielleicht auch noch ganz anders; je nachdem wie es halt besser zur Ausgaberoutine passt).

    Acorn schrieb:

    Er hat sich ungenau ausgedrückt, er meinte für jede Ziffer ein Byte und dafür braucht man zehn Chars für die darzustellen.

    Jein. Gemeint war ja z. B. sechsstelliger Score -> sechs Bytes für sechs Digits.
    Read'n'Blast my jump'n'stop-text-sprite-scroller Select A Move

    Ex-TLI (The Level 99 Industries) & Ex-TNP (The New Patriots) & Ex-TEA (The East Agents) & ?
  • M. J. schrieb:

    oobdoo schrieb:

    Hab gerade festgestellt, das bei meiner Methode keine Null übergeben werden darf. :(
    Dann stürzt das Programm ab, wenn ich die führenden Nullen wegmache. Da muß also zusätzlich noch ne Abfrage mit rein.
    Es könnte sein, daß Du eine Stelle zuviel untersuchst. Tausch doch mal

    Quellcode

    1. ld b, 5
    gegen

    Quellcode

    1. ld b, 4
    aus und kopiere den String nicht um, sondern übergib einfach die verschobene Stringadresse an die Ausgaberoutine.


    Also von 5 auf 4 bringt nix, außer das bei einer mehrstelligen Zahl eine Stelle fehlt. Oder ich bekomme lustige Bilder auf dem Schirm. :)

    Das mit dem Umkopieren, das hast Du recht. Das werde ich nachher mal ändern.



    Nachtrag:
    Geht doch mit der 4, jetzt wo ich das Umkopieren weglasse. :thumbsup:
    Mitwäre das nicht passiert! :prof:
    :syshack: Meine 3D-Drucker Teile auf thingiverse.com/oobdoo/designs :strom:
    Sammlung | 102 Bücher bzw. 28.009 Buchseiten mit Z80/8080/8085 Power
  • RE: Registerinhalte sind nicht "hex", dammich!

    Mac Bacon schrieb:

    Die verlinkte Routine konvertiert nicht von hexadezimal zu dezimal, sondern von Integer zu dezimal.
    Mit "Hexadezimal" ist eine Zahlendarstellung mit sechzehn verschiedenen Ziffern gemeint. Aus naheliegenden Gründen werden Register- und Speicherinhalte von Rechnern, deren Wortbreite durch acht teilbar ist, gern in diesem Format angezeigt. Aber solange keine Anzeige erfolgt, sind die Inhalte weder hexadezimal noch dezimal noch sexagesimal, echt jetz.

    Naja, man muss leider ein wenig rechnen, damit man eine Zahl von Hex/Int in Dezimaldarstellung konvertieren kann. Dafür eignet sich nunmal das Format am besten, mit der die CPU am besten umgehen kann: Integer. Nun muss man vorher nur noch die hexadezimal dargestellte Zahl nach Integer umwandeln, was zum Glück nicht schwer ist. :)
  • Ich zeige hier mal meine 6502 routine, die den double-dabble algorithmus implementiert, ca65 syntax:


    Quellcode

    1. .export numtostring
    2. .exportzp nc_string
    3. .exportzp nc_num
    4. NUMSTRSIZE = $a
    5. NUMSIZE = $4
    6. .zeropage
    7. nc_string: .res NUMSTRSIZE
    8. nc_num: .res NUMSIZE
    9. .code
    10. numtostring:
    11. ldx #NUMSTRSIZE
    12. lda #$0
    13. nts_fillzero: sta nc_string-1,x
    14. dex
    15. bne nts_fillzero
    16. ldy #(NUMSIZE*8)
    17. nts_bcdloop: ldx #(NUMSTRSIZE-2)
    18. nts_addloop: lda nc_string+1,x
    19. cmp #$5
    20. bmi nts_noadd
    21. adc #$2
    22. sta nc_string+1,x
    23. nts_noadd: dex
    24. bpl nts_addloop
    25. asl nc_num
    26. ldx #($ff-NUMSIZE+2)
    27. nts_rol: rol nc_num+NUMSIZE,x
    28. inx
    29. bne nts_rol
    30. ldx #(NUMSTRSIZE-2)
    31. nts_rolloop: lda nc_string+1,x
    32. rol a
    33. cmp #$10
    34. and #$f
    35. sta nc_string+1,x
    36. nts_rolnext: dex
    37. bpl nts_rolloop
    38. dey
    39. bne nts_bcdloop
    40. nts_scan: cpx #(NUMSTRSIZE-1)
    41. beq nts_digits
    42. inx
    43. lda nc_string,x
    44. bne nts_digits
    45. lda #$20
    46. sta nc_string,x
    47. bne nts_scan
    48. nts_digits: lda nc_string,x
    49. ora #$30
    50. sta nc_string,x
    51. inx
    52. cpx #(NUMSTRSIZE)
    53. bne nts_digits
    54. rts
    Alles anzeigen
    Anpassbar über die beiden Konstanten auf verschiedene Bitbreiten, hier 4 bytes, also 32 bit. Die Ausgabe ist hier rechtsbündig, wenn man das anders will muss der Code ab "nts_scan" angepasst werden.
  • Benutzer online 1

    1 Besucher