# Comparing bcd values

Status
Not open for further replies.

#### dr pepper

##### Well-Known Member
I need to compare a 3 digit unpacked bcd value against another 3 digit unpacked value.
I always seem to struggle with an efficient way to do this.

#### Jon Wilder

##### Active Member
Pack 'em, then compare -

Code:
unsigned char dig1;

unsigned char dig2;

unsigned char dig3;

unsigned char dig4;

unsigned char dig5;

unsigned char dig6;

unsigned int bcdval1 = (100 * dig1) + (10 * dig2) + dig3;

unsigned int bcdval2 = (100 * dig4) + (10 * dig5) + dig6;

if(bcdval1 == bcdval2)
{
doThis();
}
else
{
doThat();
}

Last edited:

#### dr pepper

##### Well-Known Member
Sorry I should hve said I code in asm, however I could convert to hex, but that wouldnt be very efficient.

#### misterT

##### Well-Known Member
I could convert to hex, but that wouldnt be very efficient.
Sorry, I am a bit drunk because It is my birthday, but still, this does not make much sense.. Do you mean converting the BCD value to ASCII hex? .. yes that is inefficient. Actually not very inefficient, but you would not gain anything.

Last edited:

#### KeepItSimpleStupid

##### Well-Known Member
Compare equal probably would not be that difficult:

Pseudocode

Set EQUAL bit to TRUE; Assume TRUE
Compare MSD1a equal to MSD1b; AND result to EQUAL bit
Compare MSD2a equal to MSD2b; AND result to EQUAL bit
Compare LSD3a equal to LSD3b; AND result to EQUAL bit

If EQUAL bit = TRUE then they are equal.
Sometimes you can use the carry bit.

#### dr pepper

##### Well-Known Member
This is what I did,

Code:
;
fon        movf fastens,w
subwf tens,w
skpnc
goto nx10
goto    laps1

;
nx10    movf fasones,w
subwf ones,w
skpnc
goto nx20
goto    laps1

;
nx20     movf fastenths,w
subwf tenths,w
skpnc
return
;

The code returns if tens,ones,tenths is > fatens,fasones,fastenths, carries on executing (to laps1) if the opposite.
The odd thing is that its erratic, sometimes is acts as though its less tha than when higher than, particularly when the values are less than 100.

#### KeepItSimpleStupid

##### Well-Known Member
When checking for < or > than, you have to check the MSD for <= and >=; Only the last test needs to check < and >.

Take 020 and 021

If 0<=0, you have to test 0<=2. The last test has to test 0<1. If any of the tests fail, your done.

#### NorthGuy

##### Well-Known Member
At each step there are three possibilities (not two!):

A > B : you exit with ">" result
A < B : you exit with "<" result
A = B : only then you test the next digit or exit with "=" result if it's the last digit.

#### dr pepper

##### Well-Known Member
Thanks, I get I'm incorrect.
However I still dont quite get it, I'm not understanding how to implement the >= bit.

Edit: I think I might get it, your saying do tests for < > and = on each digit, starting with the 100's, if the outcome is > then thats your answer, if the outcome is = or < then test 10's and then 1's and if one of them turns out > then the answer is >, or if you get to 1's digit whatever the outcome <> or = is the answer.

Last edited:

#### KeepItSimpleStupid

##### Well-Known Member
If the first digit is greater (MSD) than the outcome is greater. If the first digit (MSD) is less, the outcome is less. If it's equal, you have more work to do. e.g 1xxx vs 2xxx

Sometimes you can use the stack for a temporary place to store something or a memory location, You can end up with 3 bits (condition codes) when your done. Less, Greater, Equal.

So, you could pass the three locations of the BCD digits, or the digits themselves on the stack and return the result on the stack. Just depends if you can afford the extra overhead.

Last edited:

#### NorthGuy

##### Well-Known Member
... if the outcome is = or < then test 10's and then 1's.

Nope. If outcome is "=" you look at 10's. If outcome is "<" you don't look at 10's, but exit with "<" result.

Say 499 and 500. If you see 4 < 5, you stop right there and do not compare 9 to 0 as this will give you a wrong result.

#### dr pepper

##### Well-Known Member
Klunk - penny's dropped, I got it.

First check msd, if < or > thats the answer bomb out, if = then do again for msd-1 if < or > then thats the answer bomb out, if = then do again for lsd if < or > thats the answer bomb out, if = they are the same.

Looking back at my code I need to add some extra to detect < and bomb out if thats the case, the code does drop through to the next digit if one is = the other but doesnt look at one being < the other, this probably explains why it only messes up sometimes, ie when one digit is < the other.

I really want to get cracking with the code right now, but I just started a long nightshift and I have some large greasy bearings to pull and replace.

#### dr pepper

##### Well-Known Member
Heres my modded code, havent tried it yet, I just did this at work:

Code:
faslap        movf    fastens,w
subwf    tens,w
btfsc    status,z
goto    nx10        ;tens are = so goto check ones
;
movf fastens,w
subwf tens,w
skpnc
return            ;current laptime > fastest lap bomb out
goto    laps1        ;current laptime < fastest lap beep & rec
;
nx10        movf    fasones,w
subwf    ones,w
btfsc    status,z
goto    nx20        ;ones are = so goto check tenths
;
movf fasones,w
subwf ones,w
skpnc
return            ;current laptime > fastest lap bomb out
goto    laps1        ;current laptime < fastest lap beep & rec

;
nx20         movf fastenths,w
subwf tenths,w
skpnc
return            ;current laptime > fastest lap bomb out
;
laps1        movlw    d'3'        ;beep for 5 1/10's of a sec on new record
movwf    beeptime
bsf    porta,1
;

I check for the tens, ones and tenths being equal first if they are the next lower digit is tested, if not I check for < & >, higher than just bombs out and lower than turns the o/p port bit on which activates a beeper for a set time.

#### NorthGuy

##### Well-Known Member
You do not need to repeat movf/subwf twice. After you did it the first time, flags still will be there, so you can do skipnc without repeating movf/subwf.

#### dr pepper

##### Well-Known Member
Yes well spotted, I could also use skpnz.
That then gives me fast efficient code, exactly what I wanted.

Happy hangover Mr. T.

Just for clarity:

Code:
faslap        movf    fastens,w
subwf    tens,w
skpnz
goto    nx10        ;tens are = so goto check ones
;
skpnc
return            ;current laptime > fastest lap bomb out
goto    laps1        ;current laptime < fastest lap beep & rec
;
nx10        movf    fasones,w
subwf    ones,w
skpnz
goto    nx20        ;ones are = so goto check tenths
;
skpnc
return            ;current laptime > fastest lap bomb out
goto    laps1        ;current laptime < fastest lap beep & rec

;
nx20         movf fastenths,w
subwf tenths,w
skpnc
return            ;current laptime > fastest lap bomb out
;
laps1        movlw    d'3'        ;beep for 5 1/10's of a sec on new record
movwf    beeptime
bsf    porta,1
;

#### dr pepper

##### Well-Known Member
Thanks for your help guys, now working as expected.

Status
Not open for further replies.

Replies
2
Views
2K
Replies
8
Views
864
Replies
1
Views
437
Replies
15
Views
3K
Replies
47
Views
3K