Log inRegister an accountBrowse CSDbHelp & documentationFacts & StatisticsThe forumsAvailable RSS-feeds on CSDbSupport CSDb Commodore 64 Scene Database
 Welcome to our latest new user kemist ! (Registered 2018-10-19) You are not logged in 
CSDb User Forums


Forums > C64 Coding > 32bit Decimal convertion
2018-10-05 07:02
JackAsser

Registered: Jun 2002
Posts: 1458
32bit Decimal convertion

Anybody got this shitz for 32-bit numbers? http://codebase64.org/doku.php?id=base:hexadecimal_to_decimal_c..
 
... 16 posts hidden. Click here to view all posts....
 
2018-10-05 11:12
JackAsser

Registered: Jun 2002
Posts: 1458
Enjoy:

.export htd32
.proc htd32
		HTD_IN = ARGS+0		; 32-bit input
		HTD_OUT = RESULT	; 10-digit output, one digit per ZP-loc

		ldy #0 ;digit position
		:
			; Count digits on position y
			ldx #<-1 ;digit value
			:
				inx
				sec
				lda HTD_IN+0
				sbc table0,y
				sta HTD_IN+0
				lda HTD_IN+1
				sbc table1,y
				sta HTD_IN+1
				lda HTD_IN+2
				sbc table2,y
				sta HTD_IN+2
				lda HTD_IN+3
				sbc table3,y
				sta HTD_IN+3
			bcs :-

			; Rollback underflowed result
			clc
			lda HTD_IN+0
			adc table0,y
			sta HTD_IN+0
			lda HTD_IN+1
			adc table1,y
			sta HTD_IN+1
			lda HTD_IN+2
			adc table2,y
			sta HTD_IN+2
			lda HTD_IN+3
			adc table3,y
			sta HTD_IN+3

			txa
			sta HTD_OUT,y
			iny
			cpy #10
		bne :--

		rts

table0:	.byte <(1000000000>> 0),<(100000000>> 0),<(10000000>> 0),<(1000000>> 0),<(100000>> 0),<(10000>> 0),<(1000>> 0),<(100>> 0),<(10>> 0),<(1>> 0)
table1:	.byte <(1000000000>> 8),<(100000000>> 8),<(10000000>> 8),<(1000000>> 8),<(100000>> 8),<(10000>> 8),<(1000>> 8),<(100>> 8),<(10>> 8),<(1>> 8)
table2:	.byte <(1000000000>>16),<(100000000>>16),<(10000000>>16),<(1000000>>16),<(100000>>16), <(10000>>16),<(1000>>16),<(100>>16),<(10>>16),<(1>>16)
table3:	.byte <(1000000000>>24),<(100000000>>24),<(10000000>>24),<(1000000>>24),<(100000>>24), <(10000>>24),<(1000>>24),<(100>>24),<(10>>24),<(1>>24)
.endproc
2018-10-05 11:12
Perplex

Registered: Feb 2009
Posts: 213
Storing and adding XP as base-10 strings is not an option?
2018-10-05 11:13
JackAsser

Registered: Jun 2002
Posts: 1458
Quote: Storing and adding XP as base-10 strings is not an option?

Brr no! :D
2018-10-05 12:09
ChristopherJam

Registered: Aug 2004
Posts: 843
Alternately, here's my double dabble variant. No tables, 37 bytes of code including the RTS, assuming input and output in zero page. Might be able to save bytes by keeping the intermediate results in petscii rather than 0..9, but this is more readable.
.DEFINE blt bcc

scratch=$f0 ; input in scratch+10..scratch+13, output in scratch+0..scratch+9, most significant first


    jmp test


convert:
    lda#0

    ldx#9
initlp:
    sta scratch,x
    dex
    bpl initlp

    ldy#31
bitlp:

    ldx#9
correctionlp:
    lda scratch,x
    cmp#5
    blt noover
    ;carry now set
    adc#128-5-1
    ;carry now clear
    sta scratch,x
noover:
    dex
    bpl correctionlp

    ldx#13
shiftlp:
    rol scratch,x
    dex
    bpl shiftlp

    dey
    bpl bitlp

    rts


test:
    lda#13
    sta $d021
    jsr $e536
    lda#13
    jsr $ffd2
    lda#0
    sta $d021

    ldx#3
cpl:
    lda testv,x
    sta scratch+10,x
    dex 
    bpl cpl
    jsr convert

    ldx#9
codelp:
    lda#48
    ora scratch,x
    sta $040f,x
    dex
    bpl codelp
    rts


testv:
    .byte $49, $96, $02, $d2 ; 1234567890 = 0x499602d2
2018-10-05 12:36
JackAsser

Registered: Jun 2002
Posts: 1458
Awesome! Please explain the math of it
2018-10-05 12:56
Krill

Registered: Apr 2002
Posts: 1063
Seems to be a variant of that first algorithm.

Shift one bit of the binary value into the result, then avert decimal overflow for every decimal digit (when decimal digit >= 5, which would be >=10 upon the next iteration's shift) by subtracting 5 and setting decimal digit byte's MSB, which is the carry upon the next iteration's shift and will end up as the LSB of the next more significant decimal digit.

So basically you're doubling the result with every incoming bit of the argument (reflecting the binary nature of the argument) and fixing the result in every iteration (reflecting the decimal nature of the result).
2018-10-05 13:24
JackAsser

Registered: Jun 2002
Posts: 1458
Quote: Seems to be a variant of that first algorithm.

Shift one bit of the binary value into the result, then avert decimal overflow for every decimal digit (when decimal digit >= 5, which would be >=10 upon the next iteration's shift) by subtracting 5 and setting decimal digit byte's MSB, which is the carry upon the next iteration's shift and will end up as the LSB of the next more significant decimal digit.

So basically you're doubling the result with every incoming bit of the argument (reflecting the binary nature of the argument) and fixing the result in every iteration (reflecting the decimal nature of the result).


Smart approach!
2018-10-05 14:25
Krill

Registered: Apr 2002
Posts: 1063
Quoting JackAsser
Smart approach!
Indeed, it's pretty elegant. Kind of in the same "class" of algorithms with bit-wise multiplication, division and square root.
2018-10-05 16:48
ChristopherJam

Registered: Aug 2004
Posts: 843
Thanks, JackAsser! I was hoping to find something a little different, so while I did do a quick google and found the initial plus three approach elsewhere, I deliberately avoided looking at the solutions posted thus far.

Got halfway through the nybble masking etc required for the hex to BCD conversion when I had the realisation that you'd just have to unpack the nybbles for display purposes at the end anyway.

Switching to one digit per byte from the get go eliminates more than half of the instructions in the inner loop, and potentially frees up a register too.

Nice explanation of how it works, Krill.
2018-10-06 09:40
ChristopherJam

Registered: Aug 2004
Posts: 843
This one converts directly to screencodes; saves two bytes in the "copy to screen" loop, needs an extra two bytes in the converter, takes an extra 1200 or so cycles. meh. Posting for posterity anyway.

.DEFINE blt bcc
digitbase=48

scratch=$f0 ; input in scratch+10..scratch+13, output in scratch+0..scratch+9, most significant first


    jmp test


convert:
    lda#digitbase

    ldx#9
initlp:
    sta scratch,x
    dex
    bpl initlp

    ldy#31
bitlp:

    ldx#9
correctionlp:
    lda scratch,x
    cmp#5+digitbase
    blt noover
    ;carry now set
    adc#128-5-1
    ;carry now clear
noover:
    sbc #digitbase/2-1
    sta scratch,x
    dex
    bpl correctionlp

    ; note - it doesn't matter what bits you shift into the bottom
    ; of the input bytes, as they never reach the output bytes
    ldx#13
shiftlp:
    rol scratch,x
    dex
    bpl shiftlp

    dey
    bpl bitlp

    rts


test:
    lda#13
    sta $d021
    jsr $e536
    lda#13
    jsr $ffd2
    lda#0
    sta $d021

    ldx#3
cpl:
    lda testv,x
    sta scratch+10,x
    dex 
    bpl cpl
    jsr convert

    ldx#9
codelp:
    lda scratch,x
    sta $040f,x
    dex
    bpl codelp
    rts


testv:
    .byte $49, $96, $02, $d2 ; 1234567890 = 0x499602d2
Previous - 1 | 2 | 3 - Next
RefreshSubscribe to this thread:

You need to be logged in to post in the forum.

Search the forum:
Search   for   in  
All times are CET.
Search CSDb
Advanced
Users Online
Walt/Bonzai
Båtsman/HmF
iAN CooG/HVSC
Guests online: 30
Top Demos
1 Uncensored  (9.7)
2 Comaland 100%  (9.7)
3 Edge of Disgrace  (9.7)
4 Coma Light 13  (9.6)
5 The Shores of Reflec..  (9.6)
6 Wonderland XII  (9.6)
7 Lunatico  (9.6)
8 We Come in Peace  (9.6)
9 Incoherent Nightmare  (9.5)
10 Wonderland XIII  (9.5)
Top onefile Demos
1 FMX Music Demo  (9.6)
2 Daah, Those Acid Pil..  (9.6)
3 Arok 20 Invitation  (9.6)
4 Merry Xmas 2017  (9.5)
5 Pandemoniac Part 2 o..  (9.5)
6 Party Horse  (9.4)
7 Dawnfall V1.1  (9.4)
8 In Memoriam BHF  (9.4)
9 Dawnfall  (9.4)
10 Synthesis  (9.4)
Top Groups
1 Oxyron  (9.4)
2 Booze Design  (9.4)
3 Censor Design  (9.4)
4 Finnish Gold  (9.3)
5 Crest  (9.3)
Top Musicians
1 Rob Hubbard  (9.8)
2 LMan  (9.7)
3 Jeroen Tel  (9.7)
4 Linus  (9.6)
5 Drax  (9.5)

Home - Disclaimer
Copyright © No Name 2001-2018
Page generated in: 0.084 sec.