View Full Version : BCD question
keymuu
- 31st January 2009, 14:34
Hi!
Consider this code:
Divisor VAR byte[5]
H VAR WORD
b VAR BYTE
w VAR WORD
powerTen: ' for BCD conversion
select case b
case 0: w = 1
case 1: w = 10
case 2: w = 100
case 3: w = 1000
case 4: w = 10000
end select
return
H=37234
'convert to BCD and fill divisor
FOR b = 0 to 4
gosub powerTen
divisor [b] = (H/w) & $0f
next b
ENDIF
Suspecting that "(H/w) & $0f" does not work as one would think, that is
w=1 -> 37234/1 = 37234 & $F -> 4
w=2 -> 37234/10= 3723.4 & $F = 3723 -> 3
w=3 -> 37234/100=372.34 & $F= 372 -> 2
w=4 -> 37234/1000=37,234 & $F=37 -> 7
w=5 -> 37234/10000=3.7234 & $F=3 -> 3
The array is filled with 3, that is 33333 !:mad:
The goal is to find in that array 37234...
So I fail to understand what is wrong and how to amend? :o
Can anybody explain why that code doesn't work
Thanks :)
Bruce
- 31st January 2009, 16:48
I'm not sure how you're testing your Divisor array, but it should not be filled with 3's.
What you should actually be seeing is something like this;
b = 0 : Divisor 0 = 2
b = 1 : Divisor 1 = 11
b = 2 : Divisor 2 = 4
b = 3 : Divisor 3 = 5
b = 4 : Divisor 4 = 3
Divisor[b] should always contain the low byte of the result H/w anded with $0F.
If you just want to extract individual digits from H, then let PBP do it for you with the DIG
operator.
FOR b = 0 to 4
divisor [b] = H DIG b
NEXT b
This divides by 10 returning the remainder.
Example: If H = 37234 then
b = H DIG 0 = 37234/10 = 3723.4 <-- Now b = 4
b = H DIG 1 = 37234/10 = 3723.4. 3723/10 = 372.3 <-- Now b = 3
b = H DIG 2 = 37234/10 = 3723.4. 3723/10 = 372.3. 372/10 = 37.2 <-- Now b = 2
Etc,,
Your entire program gets reduced to this;
Divisor VAR byte[5]
H VAR WORD
b VAR BYTE
Main:
H=37234
'fill divisor with digits 0 to 4 from H
FOR b = 0 to 4
divisor [b] = H DIG b
NEXT b
GOTO Main
END
keymuu
- 31st January 2009, 19:53
I'm not sure how you're testing your Divisor array, but it should not be filled with 3's.
What you should actually be seeing is something like this;
b = 0 : Divisor 0 = 2
b = 1 : Divisor 1 = 11
b = 2 : Divisor 2 = 4
b = 3 : Divisor 3 = 5
b = 4 : Divisor 4 = 3
Divisor[b] should always contain the low byte of the result H/w anded with $0F.
If you just want to extract individual digits from H, then let PBP do it for you with the DIG
operator.
FOR b = 0 to 4
divisor [b] = H DIG b
NEXT b
This divides by 10 returning the remainder.
Example: If H = 37234 then
b = H DIG 0 = 37234/10 = 3723.4 <-- Now b = 4
b = H DIG 1 = 37234/10 = 3723.4. 3723/10 = 372.3 <-- Now b = 3
b = H DIG 2 = 37234/10 = 3723.4. 3723/10 = 372.3. 372/10 = 37.2 <-- Now b = 2
Etc,,
Your entire program gets reduced to this;
Divisor VAR byte[5]
H VAR WORD
b VAR BYTE
Main:
H=37234
'fill divisor with digits 0 to 4 from H
FOR b = 0 to 4
divisor [b] = H DIG b
NEXT b
GOTO Main
END
Thank you Bruce :)
Of course, I forgot the DIG and tried to do the same thing the "basic way", as a algorithm would tell you, so still wondering way it did not work?
Consider that there would not be a DIG statement then the answer wouldn't be as easy as with DIG :rolleyes: And then the original idea modified should work, shouldn't it?
Nevertheless, thank you again Bruce for being alert, you have a open mind...:cool:
I already tested it with DIG and, of course, it works like ... well... a great thing...
Bruce
- 31st January 2009, 22:26
You can do the same thing without DIG.
Main:
H=37234
'fill divisor with digits 0 to 4 from H
FOR b = 0 to 4
divisor[b] = H//10
H=H/10
NEXT b
GOTO Main
As a learning exercise, see if you can figure out why this works the same as DIG - or come
up with another method...;o}
keymuu
- 1st February 2009, 13:13
You can do the same thing without DIG.
Main:
H=37234
'fill divisor with digits 0 to 4 from H
FOR b = 0 to 4
divisor[b] = H//10
H=H/10
NEXT b
GOTO Main
As a learning exercise, see if you can figure out why this works the same as DIG - or come
up with another method...;o}
Ok, Bruce you are also a teacher :)
As earlier said, I did not remember the DIG statement and obviously not modulus divider "//" neither.
That piece of code is clear and surely should work, however, if wouldn't work as expected then again there would be something to marvel over ;) But fortunately that is not the case....
So if we compare the "original" and your excellent DIG interpreter:
a)
FOR b = 0 to 4
gosub powerTen
divisor [b] = (H/w) & $0f
next b
b)
FOR b = 0 to 4
divisor[b] = H//10
H=H/10
NEXT b
Still wondering what is wrong in a?
If we convert those code fragments to algorithms then them would be something like this:
a) divide H with power of ten (10^n, when goes n=0..4) to get rid of the decimals, isolate the lsd and store it. Do it five times.
b) isolate the lsd with H mod 10, store it and truncate H with one digit. Do it five times. Simple and clear algorithm....
I just don't grasp what is wrong with a, I do not need it anymore, just wondering :confused:
Bruce
- 1st February 2009, 18:12
Still wondering what is wrong in a?
OK let's work through this a bit to see what's wrong with a.
On the 1st pass;
H = 37234
w = 1
37234/1 = 37234. Not much help so far. This is $9172 in HEX.
$9172 has a high byte of %10010001 & a low byte of %01110010.
Since Divisor is a byte array, Divisor[b] will always be loaded with
the low byte of the result (H/w) & $0F.
Now take your low byte %01110010 & AND it with %00001111. The result is
%00000010 or 2d, which, of course, isn't what you're expecting.
Do you see how this is working?
Not yet! OK we'll do one more;
on the 2nd pass;
H = 37234
w = 10
37234/10 = 3723.4. The .4 is lost so you have 3723, which = $E8B.
$E8B has a high byte of %00001110 & a low byte of %10001011.
Now take your low byte %10001011 & AND it with %00001111. The result is
%00001011 or 11d, which again is not what you're expecting.
OK - one more pass;
On the 3rd pass H still = 37234 and w = 100.
37234/100 = 372.34. Toss the .34 and you're left with 372, which = $174.
The high byte is %00000001 the low byte is %01110100.
The low byte %01110100 & %00001111 = %00000100 or 4d. You expected a
2d, but it returned 4d. Now you know why...;o}
That's how a is working. Just follow it along. It's really simple if you just take it
apart step-by-step.
Powered by vBulletin® Version 4.1.7 Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.