Searching \ for 'Binary to BCD Conversion' in subject line. ()
Help us get a faster server
FAQ page: techref.massmind.org/techref/index.htm?key=binary+bcd+conversion
Search entire site for: 'Binary to BCD Conversion'.

Truncated match.
'Binary to BCD Conversion'
1998\04\27@142103 by

Dear All

Cannily realising that I'd want a binary to BCD conversion routine
in the future, I carefully filed and kept a brief thread on the subject
from a few weeks ago. Slightly less cannily, I can't understand what
it's doing. Can anyone point me in the right direction, pseudo-code-
wise? Let's say I have a byte 'count'; if it can run to FFh, I guess I
need 12 bytes of BCD (3 lots of 4 bytes?) to encode '255'.  Or would
it be customary to stop at 63h (99 dec.)? Either way, in English (or some
approximation) what am I doing? This was the routine:

{Quote hidden}

I know what all the opcodes mean, but that's not quite the same as
understanding the whole thing!

And if I wanted to go to 9999 decimal (270Fh) could I scale it up easily?

Any help greatly appreciated.

Regards

John M

To me it looks more like a BCD to binary  conversion. BCD=16*tens+ones. To
get it on to binary you require 10*tens+ones. so you do a BCD-8*tens+2*tens.

If you happen to get a binary to BCD converter, please forward it to be. I'm
really interested.

PS. It might be possible to get a binary to BCD converter using the same logic.
Am trying to work it out.

At 17:01 4/27/98 +0100, John Midgley wrote:
{Quote hidden}

with best wishes and regards
Sujay Sirur

Email: sirurgiasbg01.vsnl.net.in
Home: 604, Chitrapur Housing Society, Plot no 68, 15th Cross, 8th Main,
Malleshwaram
Bangalore 560 055. INDIA   Tel. no: 91-80-344-3688

=================================================================
If love is in the air, then its polluted :-) :-)
=================================================================

-----Original Message-----
From: Sujay Sirur <sirurGIASBG01.VSNL.NET.IN>
To: PICLISTMITVMA.MIT.EDU <PICLISTMITVMA.MIT.EDU>
Date: Monday, April 27, 1998 9:51 PM
Subject: Re: Binary to BCD Conversion

>If you happen to get a binary to BCD converter, please forward it to be.
I'm
>really interested.
>

if cpu cycle are not critial you can try this routine. it converts a byte to
decimal 0 - 255. i just cut it out of an old project so i hope i got all the
part needed. if not please email me.

michael

;
; Convert a binary byte to ascii then to display segments
;
; Store binary data in 'W' and index points to first display area.
;
i_to_a
#define left      Local_1
#define digit     Local_2
#define power     Local_3
#define blanking  Local_bit_1
bsf     blanking
movwf   left
movlw   100
movwf   power
call    ia_label1
movlw   10
movwf   power
call    ia_label1
movlw   1
movwf   power
bcf     blanking

ia_label1
clrf    digit
ia_loop         movf    power,w
subwf   left,w
btfss   STATUS,C
goto    ia_end
movwf   left
incf    digit,f
goto    ia_loop
ia_end          movf    digit,w
movwf   indirect
btfss   STATUS,Z        ; is this digit zero?
goto    ia_L1
btfss   blanking        ; is blanking set and digit zero
goto    ia_L1
movlw   " "             ; load blank display segments
goto    ia_L2
ia_L1           movlw   0x30
bcf     blanking        ; clear blanking flag
ia_L2           addwf   indirect,f      ; convert to ascii
incf    index,f
return

On Tue, 28 Apr 1998 08:22:44 +0500 Sujay Sirur
<sirurGIASBG01.VSNL.NET.IN> writes:

>PS. It might be possible to get a binary to BCD converter using the
>same logic.
>Am trying to work it out.
The routine originally posted is indeed a BCD to binary converter.  A
binary to BCD converter would be based on dividing by 10, rather than
multiplying.  For single byte numbers, it is practical to repeatedly
subtract 10, counting the number of subtractions needed to reduce the
number to less than 10.  The number of subtractions required is the tens
digit, and the remaining number is the ones digit.

The routine attached below is some not too elegant code from one of my
recent projects.  It converts a number from 0 to 99 to two BCD digits
using a repeated subtraction method.  The repeated subtraction method
becomes unweildy for numbers larger than 999.  Either long division by 10
or the "BCD multiply by 2" routine should lead to smaller and faster
code.
;-------------
cvdec
; Converts the 1-byte number in bin to decimal.  Number must be less than
100
; for correct result of course.  Result returned as packed BCD in tmp.
; Number in bin is destroyed. (On exit, bin contains the ones digit with
the
;  high 4 bits zero)
;
movlw   .10             ;Constant to use
cvdecl
incf    tmp,f           ;Inc. the tens digit.
subwf   bin,f           ;Subtract 10
skpnc                   ;Skip if bin was less than 10.
goto    cvdecl          ;Subtract again.
; Here with tens digit + 1 in low bits of bcd, and ones digit - 10
(negative)
;  in bin.
addwf   bin,f           ;Restore ones digit (know now 0
to 9).
decf    tmp,f           ;Fix tens digit.
swapf   tmp,w           ;Get tens digit to high bits.
iorwf   bin,w           ;OR in the ones digit.
movwf   tmp             ;Put result back.
return
;----------------

_____________________________________________________________________
Get completely free e-mail from Juno at http://www.juno.com
Or call Juno at (800) 654-JUNO [654-5866]

>To me it looks more like a BCD to binary  conversion

Well that would certainly help to explain why it didn't make
sense to me. Now, lets see if I can understand it the other
way round!

John M

> Van: John Midgley <John.MidgleyENORFOLK-HA.ANGLOX.NHS.UK>> > Aan: PICLISTMITVMA.MIT.EDU
> Onderwerp: Binary to BCD Conversion
> Datum: maandag 27 april 1998 18:01
>
> Dear All
>
> Cannily realising that I'd want a binary to BCD conversion routine
> in the future, I carefully filed and kept a brief thread on the subject
> from a few weeks ago. Slightly less cannily, I can't understand what
> it's doing. Can anyone point me in the right direction, pseudo-code-
> wise? Let's say I have a byte 'count'; if it can run to FFh, I guess I
> need 12 bytes of BCD (3 lots of 4 bytes?) to encode '255'.  Or would

I gather that you mean '3 lots of 4 _bits_' :-)

> it be customary to stop at 63h (99 dec.)? Either way, in English (or some
> approximation) what am I doing? This was the routine:

[Cut]

You will have heard by now that the above routine was a 2-digit packed
BCD-to-Binary routine ...

I've got a Binary-to-BCD routine using a long-tail division (homebrew) for
two bytes (resulting in 5 digits uncompressed BCD). If you are interrested
..

> And if I wanted to go to 9999 decimal (270Fh) could I scale it up easily?

If you are only counting (not converting the output of a calculation) you
could
opt for counting BCD-wise. said otherwise : increment the BCD-counter and

> Any help greatly appreciated.
>
> Regards
>
> John M

Greetz,
Rudy Wieser

> I gather that you mean '3 lots of 4 _bits_' :-)

Oops

> You will have heard by now that the above routine was a 2-digit packed
BCD-to-Binary routine ...

Oops again

> If you are only counting (not converting the output of a calculation) you
> could opt for counting BCD-wise. said otherwise : increment the BCD-
> counter and BCD-adjust the result.

I did ponder this one; I could do it either way, but I thought that the binary
to BCD conversion would be a solution that I'd use again.

> I've got a Binary-to-BCD routine using a long-tail division (homebrew) for
> two bytes (resulting in 5 digits uncompressed BCD). If you are interrested

I sure am. Thoroughly commented, I trust? I'm still trying to puzzle out how
it works. Horowitz and Hill just say 'It's complicated' which is not helpful. I'
ve
even drawn up a K-map and stared at it for a while. I stopped when I got a

I'd be most grateful for sight of your routine.

Kind regards

John M

If you want a quick program but slow running one,
I have seen where a one byte to bcd conversion
first subtracts 100 from the binary number,
and when it subtracted too much, it adds 100 back into
the binary number.

Then it subtracts 10 from the binary number until it goes
too far, then add 10 back in to binary number.

Then does the same for 1.

This may take 23 subtractions, so it is not fast running.

Bill C.  billcornutt.com

compare 200
if greater, subtract 200, add 2 to hundreds count
compare 100
if greater, subtract 100, add 1 to hundreds count

compare 80
if greater, subtract 80, add 8 to tens count
compare 40
if greater, subtract 40, add 4 to tens count
compare 20
if greater, subtract 20, add 2 to tens count
compare 10
if greater, subtract 10, add 1 to tens count

same for 'ones' and extending beyond to 16 bits or more. Hefty on code
space but fairly rapid. Although I've only tried it on a z8 so I don't
know how well it can be done on a Pic.

Bill Cornutt wrote:
{Quote hidden}

----------------------------------------------------------------
Chris Savage                    chriscti-vision.demon.co.uk
Software Engineer               +44 385 396 993
CTIVision Ltd, Egham, UK
----------------------------------------------------------------

On Wed, 29 Apr 1998 14:21:20 +0100 Chris Savage
<chrisCTI-VISION.DEMON.CO.UK> writes:
>
>        compare 200
>        if greater, subtract 200, add 2 to hundreds count
[....]

This is an interesting method. Maybe some automation could be done by
shifting the powers of 10 right for each digit.  (i.e. 800, 200, 400,
100, then 80, 40, 20, 10).  It still has to store a constant for each
power of 10 like the repeated subtraction method so it will use quite a
bit of code space for larger numbers.  It's a little similar to long
division, but also an enhancement of repeated subtraction.

If speed is important, the "BCD multiply by 2" routine is likely best on
large numbers.  It's also very compact since no powers of 10 are stored.
Long division also features compact size and easy expansion to large
numbers.  The core of it can be re-used for other division tasks.  With
conventional long division, all the compare and subtract operations are
with 10, so single-byte math can be used regardless of the size of the
input number.  Repeated subtraction methods require multiple-byte math
once the input number is larger than 256.

I'll attempt to describe how long division can be applied to BCD
conversion:

Compute N = N/10.  Remainder is a BCD digit from 0 to 9.  Save the
remainders and repeat until N=0.  The first remainder computed is the
rightmost (least significant) BCD digit.

For example, consider 179.
179/10 = 17, remainder 9
17 /10 =  1, remainder 7
1  /10 =  0, remainder 1.

Since the result is now zero the process is done.  This inherently
repeat the process a fixed number of times large enough to accomodate the
largest number expected.  Subsequent steps will find 0/10 = 0, remainder
0.

If you're using an LCD panel the result can be written out "on the fly"
by configuring the panel to move the cursor right to left instead of as
normal left to right.  Other forms of output such as RS-232 would require
saving the results in RAM then outputting them in proper MSD first order.

_____________________________________________________________________
Get completely free e-mail from Juno at http://www.juno.com
Or call Juno at (800) 654-JUNO [654-5866]

----------
>
>         compare 200
>         if greater, subtract 200, add 2 to hundreds count
>         compare 100
>         if greater, subtract 100, add 1 to hundreds count
>
>         compare 80
>         if greater, subtract 80, add 8 to tens count
>         compare 40
>         if greater, subtract 40, add 4 to tens count
>         compare 20
>         if greater, subtract 20, add 2 to tens count
>         compare 10
>         if greater, subtract 10, add 1 to tens count

No need to do anything for 'ones' as the result of the above
subtractions will leave the ones value.  But the test may should
be 'greater or equal'.

And a right shift of the 200 value gives a 100 value.   The same
shifting 80 to get the next compare/subtraction value...
Is a shift quicker than a load?

Also if the 'test for 80' is true, then no need to 'test for 40'

Bill C.   billcorutt.com

{Quote hidden}

Bill Cornutt wrote:
>
> ----------
> No need to do anything for 'ones' as the result of the above
> subtractions will leave the ones value.  But the test may should
> be 'greater or equal'.

Yer right. And I wrote the above without reference to my code sO I
forgot I'd done that. Honest.
>
> And a right shift of the 200 value gives a 100 value.   The same
> shifting 80 to get the next compare/subtraction value...
> Is a shift quicker than a load?
>
> Also if the 'test for 80' is true, then no need to 'test for 40'

But I didn't do that. Thanks.

>
> Bill C.   billcorutt.com
>

--
----------------------------------------------------------------
Chris Savage                    chriscti-vision.demon.co.uk
Software Engineer               +44 385 396 993
CTIVision Ltd, Egham, UK
----------------------------------------------------------------

On Thu, 30 Apr 1998 08:37:34 +0100 Chris Savage
<chriscti-vision.demon.co.uk> writes:
>Can you point me to an elaboeation of this method, please. Can't find
>anything in the archive.

A version of the routine can be found in the Microchip application note
AN526.  An 8-bit routine based on repeated subtraction is presented, then
a 16-bit "BCD multiply by 2" routine.  There isn't a lot of explanation
there, but it does work.  The key to the routine is "adjusting" a packed
BCD number so shifting it left one bit multiplies it by 2.  If a digit is
more than 4, 3 is added to it:

0               0       0
1               1       2
2               2       4
3               3       6
4               4       8
5               8       (1) 0
6               9       (1) 2
7               A       (1) 4
8               B       (1) 6
9               C       (1) 8

As you can see, the adjustment process makes it simple to multiply by 2
in BCD.  With this ability, the binary number is shifted into the BCD
number one bit at a time.  The MSB of the binary number is shifted into
the LSB of the adjusted BCD number, so the new value of BCD is either
BCD*2 or BCD*2+1 depending on the value of the binary bit.  After doing
all the bits, the BCD number is complete.  It is simple to expand the
routine's ability to larger numbers by adding more RAM and doing more
shifts.

The Microchip routine can be optimized some.  I posted a complete
optimized routine a while ago, but I can't find it now either.  Here it
is again.  The routine is for 24 bits being converted to 8 digits.  Both
numbers are in "little-endian" format: LSB first in memory.  The routine
tests a bit in FSR to control the inner loop, requiring 'bcd' to be at a
specific place in RAM (like 0C to 0F).

; Rewrite of b2bcd for less space; inlined it.
;b2bcd
movlw   d'24'
movwf   ii
clrf    bcd             ;clear result to all 0.
clrf    bcd+1
clrf    bcd+2
clrf    bcd+3
b2bcdl
movlw   bcd             ;Point at first bcd
movwf   FSR
; Copy of 'adjbcd'.  OK to adjust the first time before shifting.
b2bcdil
movlw   h'33'
btfsc   INDF,3
andlw   h'f0'           ;Low result >7 . OK (take the 3
out)
btfsc   INDF,7
andlw   h'0f'           ;Hi > 7 OK.
subwf   INDF,f          ;any results <=7, subtract
back.
incf    FSR,f           ;Inc. pointer for next time
; bcd placed at known address, so bits in FSR could be used for loop
control
btfss   FSR,4           ;When FSR reaches 0x10, done.
goto    b2bcdil         ;If not done, do the inner
loop again.

rlf     bin+0,f
rlf     bin+1,f
rlf     bin+2,f         ;Get another bit out of bin.
rlf     bcd+0,f         ;Put bit into bcd.
rlf     bcd+1,f
rlf     bcd+2,f
rlf     bcd+3,f

decfsz  ii,f            ;Do more?
goto    b2bcdl          ;Yes.

_____________________________________________________________________
Get completely free e-mail from Juno at http://www.juno.com
Or call Juno at (800) 654-JUNO [654-5866]

At 10:49 30/04/98 -0400, you wrote:

Improving the method discussed earlier:
taking X=byte and converting to BCD digits H,T,U

in pseudoBasic!!

H=0
T=0
U=X
if U>=200 then H=H+2: U=U-200: Goto Check40 'NUMBER WILL BE <=55
if U>=100 then H=H+1: U=U-100
if U>=80 then T=T+8: U=U-80: Goto Check10 'NUMBER WILL BE <=19
Check40:
if U>=40 then T=T+4: U=U-40
if U>=20 then T=T+2: U=U-20
Check10:
if U>=10 then T=T+1: U=U-10

should take 24 to 48 instructions on a pic depending on X

_____________________________________________________
Osama ALASSIRY  osamaqatar.net.qa osamaalassiry.com
http://www.alassiry.com

This reminds me of a game I use to play with a fellow
programmer.  When we had a bug we would look it over
and then play the game "Fix That Bug", based on the
game "Name That Tune".

"I can fix that bug in five bytes."
"I can fix that bug in four bytes."
"Fix that bug!"

Bill C.   billcornutt.com

----------
{Quote hidden}

'Binary to BCD Conversion'
1998\05\03@025718 by
Bill Cornutt wrote:

> And a right shift of the 200 value gives a 100 value.   The same
> shifting 80 to get the next compare/subtraction value...
> Is a shift quicker than a load?

If the value is in a file register and the carry is already clear,
yes.  This is particularly useful if you extend this procedure to multi-
byte values.

> Also if the 'test for 80' is true, then no need to 'test for 40'

Well, Osama ALASSIRY <osamaALASSIRY.COM> suggested code:

{Quote hidden}

If you are using fixed subtractions rather than shifts, and since each
"IF" is coded <skip conditional> <GOTO else code> <IF code> (<GOTO ...>)
<else code> then the one-instruction-less optimisation of the above is:

H=0: T=0: U=X

C200:
if U=>200 goto CG200
C100:
if U<100 goto C80
H=H+1: U=U-100
C80:
if U<80 goto C40
T=T+8: U=U-80
goto C10

CG200:
H=H+2: U=U-200
C40:
if U<40 goto C20
T=T+4: U=U-40
C20:
if U<20 goto C10
T=T+2: U=U-20
C10:
if U<10 goto C00
T=T+1: U=U-10
C00:

FWIW!

Cheers,
Paul B.

On Sun, 3 May 1998, Paul B. Webster VK2BZC wrote:

>   If you are using fixed subtractions rather than shifts, and since each
> "IF" is coded <skip conditional> <GOTO else code> <IF code> (<GOTO ...>)
> <else code> then the one-instruction-less optimisation of the above is:
>
<snip>
>
>   FWIW!

about 33 instructions. However, to up the 1-byte less ante, there's a
trick that allows you to use binary comparisons for a 28-cycle conversion.
I divulge those tricks tomorrow...

However for the decimal version, this little trick works well:

MOVF    bin,W

RLF     tens_and_ones,F   ;Get the (inverted) carry
BTFSS   tens_and_ones,0   ;If there was no carry
ADDLW  200               ;put back the 200

. . .

Followed later by a COMF (or some other bit inverting trick) to get
the proper polarity.

Scott

Bill Cornutt wrote:

> "I can fix that bug in five bytes."

Here's a 24-instruction solution with a little looping:
Explanation:
anick.simplenet.com/piclist/Oct97/0369.html
Code:
http://anick.simplenet.com/piclist/Oct97/0312.html

It's based on what Payson affectionately calls his 'wonderful 16-bit
binary to BCD algorithm':

www.iversoft.com/cgi-bin/lwgate/PICLIST/archives/March97/date/article-0.h
tml

It's been a year since it's been posted, perhaps it's time
again?)

Here's the 28-cycle (non-looping) version that I promised yesterday.
It's based on binary comparisons. It's one of those routines that
is very difficult to comment. So I didn't. However it takes advantage
of this little trick to quickly ascertain the ones' digit:

If you look at the ones' digit for 2^N you see this pattern:
n = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 ...
2^n % 10 = 1, 2, 4, 8, 6, 2, 4, 8, 6, 2, 4, 8 ...

If it wasn't for the annoying 6's, you could simply sum the nibbles to
get and get the ones' digit (after a relatively simple binary to BCD
conversion). However, it's simple enough to test if bit 4, 8,...
are high and to subtract 1 and then add 6 (or simply add 5) if they
are.

The second observation is that the sum of all of the tens' digits is
less than 16, and thus can fit into one nibble. This simplifies having
to deal with overflow until after all of the digits have been added
together.

The third observation is that the BCD result is greater than 200 only
if the most significant bit is set.

;********************************
;binary_to_bcd - 8-bits
;
;Input
;  bin  - 8-bit binary number
;Outputs
; hundreds - the hundreds digit of the BCD conversion
; tens_and_ones - the tens and ones digits of the BCD conversion

binary_to_bcd:

CLRF    hundreds
SWAPF   bin,W
ANDLW   00001111b
SKPNDC
SKPNDC
SKPDC

BTFSC   bin,4
ADDLW   0x16 - 1 + 0x6
SKPDC

BTFSC   bin,5

BTFSC   bin,6

BTFSC   bin,7

RLF     hundreds,F
BTFSS   hundreds,0

MOVWF   tens_and_ones
BTFSC   bin,7
INCF   hundreds,F

Scott

At 16:16 5/3/98 +1000, Paul B. Webster VK2BZC wrote:
{Quote hidden}

Hi everybody,

sorry about butting into the link so late. But just got an idea, (maybe dumb
on second thoughts). How about doing a binary search?

H=0; T=0; U=X;

while(U.bit7)                                   /*if bit7, the definately >
128 */
{        U=U-120
H=H+1
T=T+2
}

while(U.bit6)                                   /*if bit 6 ....  */
{        U=U-60
T=T+6
}

while(U.bit5)
{        U=U-30
T=T+3
}

while(U.bit4)
{        U=U-10
T=T+1
}

if(U>=10)
{       U=U-10
T=T+1
}

if(T>=20)                                       /* if more than 20 tens */
{       H=H+2
T=T-20
}
elseif(T>=10)
{       H=H+1
T=T-10
}

with best wishes and regards
Sujay Sirur

Email: sirurgiasbg01.vsnl.net.in
Home: 604, Chitrapur Housing Society, Plot no 68, 15th Cross, 8th Main,
Malleshwaram
Bangalore 560 055. INDIA   Tel. no: 91-80-344-3688

Sujay Sirur wrote:

> How about doing a binary search?

> while(U.bit7)         /*if bit7, the definately
> 128 */
> {        U=U-120
>         H=H+1
>         T=T+2

I think the only real "problem" with regard to optimisation, is that
there are still seven major comparisons here, six in the shortest path,
and the execution of the above takes three adjustments to variables.

Also, when comparing these steps, it is as well to remember that
adding or subtracting one to (or doubling) a variable is one
instruction, but any other number requires two.

Have I missed something clever, but I don't see why you specified
"while" loops?

Cheers,
Paul B.

Paul B. Webster VK2BZC wrote:
>
> Sujay Sirur wrote:
>
> > How about doing a binary search?

Hmmm. Clever.

{Quote hidden}

Because Sujay 'compares' 2^n but subtracts (2^n - (2^n % 10)). So
for 255, you check the MSB and say 'yeah, it's greater than 127 thus
I'll subtract 120'. However, this still leaves the MSB set. Hence the
while.

My only comment about the code is, well, I don't think it can solve
the problem in 5 bytes.

Scott

bin2bcd:
clrf    bcdto           ;clear tens and ones
clrf    bcdh            ;clear hundreds
movlw   8               ;8 bits to process
movwf   cnt

loop    rrf     bin             ;get lsb
skpnc                   ;compare if set
decfsz  cnt             ;loop for 8 times
goto   loop
skpnc                   ;if msb is set add 1 in hundred
incf   bcdh            ; 'coz last constant is only 28
return

decf    cnt,w
retlw   28 + 66 ;lacking 1
retlw   64 + 66
retlw   32 + 66
retlw   16 + 66
retlw   8 + 66
retlw   4 + 66
retlw   2 + 66
retlw   1 + 66

movlw   0
skpdc
iorlw  6
skpc
iorlw  60
subwf   bcdto
andlw   60
skpz
incf   bcdh
return

This routine is similar to a binary search.
Maximum of 8 bcd additions if binary is 255.

Reggie

'Binary to BCD conversion'
2003\05\29@233606 by
As a novice, I studied the "AN-526". Tried to run the program "Appendix H: Binary (16bit) to BCD".

However, the result in R0, R1, R2 become 06,85,53 in stead of 06,55,35 when converting the number B'11111111' in both H_byte & L_byte.

I traced every step but can't find where is the problem?

Not yet understand the algorithm of such a conversion, my first step is to follow the codes; even so the result is not correct.

The sample routine was publilshed many years ago, there must be many people ever study it. I would appreciate if someone hints me the blind point(s) where I stuck?

Regards

Paul Tsai

--
http://www.piclist.com hint: The PICList is archived three different
ways.  See http://www.piclist.com/#archives for details.

More... (looser matching)
- Last day of these posts
- In 2003 , 2004 only
- Today
- New search...