?
Solved

Convert integer to BCD

Posted on 2003-03-26
9
Medium Priority
?
1,074 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Industry Leaders: 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

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

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

Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
The goal of this video is to provide viewers with basic examples to understand and use pointers in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to use strings and some functions related to them in the C programming language.

752 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