?
Solved

Convert integer to BCD

Posted on 2003-03-26
9
Medium Priority
?
1,112 Views
Last Modified: 2008-03-10
I am looking for a code snippet that shows how to convert an unsigned long integer (4 bytes) too either a packed (preferable) or unpacked BCD format. I would like to see this done using a method simular to the "Add Three" algorithm - not with division operations. The code snippet needs to be in C -- I have two examples of how to do this in PIC assembly, but I'm not certain how the F register works so I can't translate them. I will post the PIC assembly code if someone requests it. My motivation is intellectual curiosity.
0
Comment
Question by:cjs2895
  • 3
  • 3
  • 2
  • +1
9 Comments
 
LVL 30

Expert Comment

by:Mayank S
ID: 8216327
Which way do you want the output to be? I don't think that the C compiler will display a number in BCD format. It'll display it in decimal, hex, etc.... do you want a string to hold the binary equivalent of the number in BCD?

Mayank.
0
 
LVL 10

Expert Comment

by:substand
ID: 8216861
here's a program i just wrote.  since you want 4 bytes, there are a max of 10 digits (you can increase this in the code if you want, by changing the size of my array)...

this is in packed (as in, 4 bits for each digit- i take it to assume, rather than 8).  the output has 4 bits representing each digit, and each 4 bits is separated by a space:

#include <stdio.h>

int main(void)
{

     unsigned long ourInt=123456789;
     int bcdBits[40], currentBlock=-1, i;
     /*since you asked for 4 bytes, we have 32 bits,
     so the highest number is 10 digits.  For packed
     BCD we need 4 "bits" for each digit, and there
     are a max of 10 digits. */

     for (i=0; i<40; i++) bcdBits[i]=0;

     while (ourInt >= 1)
     {
          currentBlock++;

          switch (ourInt%10)
          {
         
               case 0:
                    bcdBits[39-currentBlock*4-3]=0;
                    bcdBits[39-currentBlock*4-2]=0;
                    bcdBits[39-currentBlock*4-1]=0;
                    bcdBits[39-currentBlock*4]=0;
                    break;
               case 1:
                    bcdBits[39-currentBlock*4-3]=0;
                    bcdBits[39-currentBlock*4-2]=0;
                    bcdBits[39-currentBlock*4-1]=0;
                    bcdBits[39-currentBlock*4]=1;
                    break;
               case 2:
                    bcdBits[39-currentBlock*4-3]=0;
                    bcdBits[39-currentBlock*4-2]=0;
                    bcdBits[39-currentBlock*4-1]=1;
                    bcdBits[39-currentBlock*4]=0;
                    break;
               case 3:
                    bcdBits[39-currentBlock*4-3]=0;
                    bcdBits[39-currentBlock*4-2]=0;
                    bcdBits[39-currentBlock*4-1]=1;
                    bcdBits[39-currentBlock*4]=1;
                    break;
               case 4:
                    bcdBits[39-currentBlock*4-3]=0;
                    bcdBits[39-currentBlock*4-2]=1;
                    bcdBits[39-currentBlock*4-1]=0;
                    bcdBits[39-currentBlock*4]=0;
                    break;
               case 5:
                    bcdBits[39-currentBlock*4-3]=0;
                    bcdBits[39-currentBlock*4-2]=1;
                    bcdBits[39-currentBlock*4-1]=0;
                    bcdBits[39-currentBlock*4]=1;
                    break;
               case 6:
                    bcdBits[39-currentBlock*4-3]=0;
                    bcdBits[39-currentBlock*4-2]=1;
                    bcdBits[39-currentBlock*4-1]=1;
                    bcdBits[39-currentBlock*4]=0;
                    break;
               case 7:
                    bcdBits[39-currentBlock*4-3]=0;
                    bcdBits[39-currentBlock*4-2]=1;
                    bcdBits[39-currentBlock*4-1]=1;
                    bcdBits[39-currentBlock*4]=1;
                    break;
               case 8:
                    bcdBits[39-currentBlock*4-3]=1;
                    bcdBits[39-currentBlock*4-2]=0;
                    bcdBits[39-currentBlock*4-1]=0;
                    bcdBits[39-currentBlock*4]=0;
                    break;
               case 9:
                    bcdBits[39-currentBlock*4-3]=1;
                    bcdBits[39-currentBlock*4-2]=0;
                    bcdBits[39-currentBlock*4-1]=0;
                    bcdBits[39-currentBlock*4]=1;
                    break;

          }
         
          ourInt=ourInt/10;
     }

     for(i=1; i<41; i++)
     {
          printf("%d",bcdBits[i-1]);
          if (i%4 == 0) printf(" ");
     }

return 0;
}
 
0
 
LVL 10

Expert Comment

by:substand
ID: 8216876
that code prints out:

0000 0001 0010 0011 0100 0101 0110 0111 1000 1001

since our input was the unsigned long int ourInt=123456789

we see that each 4 bits represents

0 1 2 3 4 5 6 7 8 9 = 123456789


you can substitute any unsigned long int for 123456789

....

hope that helps
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 5

Accepted Solution

by:
Kocil earned 2000 total points
ID: 8216910
I'm bidding for 500 points :)

/* binary to bcd, add-3 algorithm */
/* result in array of char (not packed) */

  #include <stdio.h>
  #include <stdlib.h>
  #include <conio.h>

  #define BIN_SIZE 4
  #define MSB_MASK 0x80000000L
  #define BCD_SIZE 13

  typedef unsigned long BIN;
  typedef unsigned char BCD[BCD_SIZE];

  main()
  {
     BIN bin1,bin;
     BCD bcd;
     int i,j,k,carry;
     char temp[9];


     printf("enter number:");
     scanf("%lu", &bin1);
     bin=bin1;

     for (i=0; i<= BCD_SIZE; i++) bcd[i]=0;
     printf("\n     BCD  BIN\n");
     for (i=0; i<8*BIN_SIZE; i++) {
        /* check for overflow */
        for (j=0; j<BCD_SIZE; j++) {
           if (bcd[j] >= 5) {
             bcd[j] += 3;
             /* printout for checking */
             for (k=BCD_SIZE; k--; ) printf("%4s ", itoa(bcd[k],temp,2));
             printf(" %x\n", bin);
           }
        }
  #include <stdio.h>
  #include <stdlib.h>
  #include <conio.h>

  #define BIN_SIZE 4
  #define MSB_MASK 0x80000000L
  #define BCD_SIZE 13

  typedef unsigned long BIN;
  typedef unsigned char BCD[BCD_SIZE];

  main()
  {
     BIN bin1,bin;
     BCD bcd;
     int i,j,k,carry;
     char temp[9];


     printf("enter number:");
     scanf("%lu", &bin1);
     bin=bin1;

     for (i=0; i<= BCD_SIZE; i++) bcd[i]=0;
     printf("\n     BCD  BIN\n");
     for (i=0; i<8*BIN_SIZE; i++) {
        /* check for overflow */
        for (j=0; j<BCD_SIZE; j++) {
           if (bcd[j] >= 5) {
             bcd[j] += 3;
             /* printout for checking */
             for (k=BCD_SIZE; k--; ) printf("%4s ", itoa(bcd[k],temp,2));
             printf(" %x\n", bin);
           }
        }
        /* shift right */
        carry = (bin & MSB_MASK) == MSB_MASK;
        bin = bin << 1;
        for (j=0; j<BCD_SIZE; j++) {
           bcd[j] = (bcd[j] << 1) | carry;
           carry = (bcd[j] & 0x10) == 0x10;
           bcd[j] = bcd[j] & 0xF;
        }
       /* printout for checking */
        for (k=BCD_SIZE; k--; ) printf("%4s ", itoa(bcd[k],temp,2));
        printf(" %x\n", bin);
     }
     printf("BIN = %lu\n", bin1);
     printf("BCD = ");
     for (k=BCD_SIZE; k--; ) printf("%d", bcd[k]);
  }



0
 
LVL 5

Expert Comment

by:Kocil
ID: 8216925
Awww ... sorry. It was double copy.
Please, delete code from the first
#define <stdio.h>
....

until the second
#define <stdio.h>
0
 
LVL 1

Author Comment

by:cjs2895
ID: 8259221
Folks, sorry that I have neglected to review your answers in a timely manner. I will review these over the weekend.
0
 
LVL 10

Expert Comment

by:substand
ID: 8259319
thanks- i was beginning to wonder =) lol.

0
 
LVL 1

Author Comment

by:cjs2895
ID: 8280523
I have accepted Kocil's answer as the correct solution to this question. One of the parameters laid out in the original question was that I wanted to see a solution that didn't require a division. The algorithm from "substand" used a modulus operation which is actually a division -- it just returns the remainder instead of the quotient. I should also note that Kocil's answer actually used the "add-3" algorithm to accomplish its goal -- an algorithm that apparently is not well known (then again, who uses BCD these days?). I'm very happy to see that algorithm written in C. Good work Kocil! Your knowledge of esoteric algorithms and a correct C implementation earns you an A.
0
 
LVL 5

Expert Comment

by:Kocil
ID: 8281401
Thanks mate.
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Have you thought about creating an iPhone application (app), but didn't even know where to get started? Here's how: ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Important pre-programming comments: I’ve never tri…
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use conditional statements in the C programming language.

621 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question