Himadri Ganguly
Himadri Ganguly

Reputation: 743

BCD to Decimal And Decimal to BCD

I am writing a library for RTC module in Arduino where the data is stored in BCD. I know how the Decimal number is converted into BCD but having some problem while writing it programmatically. After searching the internet I got two formulas which are as follows and working perfectly but cannot understand how it is calculating.

1. Formula1

DEC to BCD

(value / 10 * 16) + (value % 10)

Example

DEC -> 40 which converted to 01000000 in BCD which is again equal to 64.

So if I put into the formula I get the same result.

(40/10 * 16) + (40%10)
= (4*16) + 0
= 64

BCD to DEC

(value / 16 * 10) + (value % 16)

2. Formula2

DEC to BCD

val + 6 * (val / 10)

BCD to DEC

val - 6 * (val >> 4)

If anyone can explain it in details it will be helpful.

Thanks to all in advance.

Upvotes: 4

Views: 19539

Answers (3)

Vlad
Vlad

Reputation: 1

Maybe someone will need it,

//BIN -->BCD
#include "arduino.h" 
 unsigned long a =0;
 unsigned long x=0;
 unsigned long y=0;
 unsigned long c=0;
 unsigned long b=0;
  int d=0;
  int e=0;
  byte f=0;
 //=================================
void setup() {

 Serial.begin (9600); 
 unsigned long start = micros();

 unsigned long val =964827;
   x=val;
  if(x>100000){
  a=x/100000;
  x=x-(a*100000); 
  };
  if(x>10000){
  b=x/10000;       
  x=x-(b*10000);
   };
  if(x>1000){
  c=x/1000;       
  x=x-(c*1000);
   };
  if(x>100){
  d=x/100;       
  x=x-(d*100);
   };
  if(x>10){
  e=x/10;       
  x=x-(e*10);
   };


  Serial.println (a,DEC);
  Serial.println (b,DEC);
  Serial.println (c,DEC);
  Serial.println (d,DEC);
  Serial.println (e,DEC);
  Serial.println (x,DEC);

  unsigned long end = micros();
  unsigned long delta = end - start;
  Serial.println(delta); 





 }

  void loop() {
  // put your main code here, to run repeatedly:

 }

Upvotes: -1

Ivan
Ivan

Reputation: 1

some code for 16 bit:

uint16_t decToBcd16(uint16_t val)
{
    return((((val / 1000) % 10) << 12) | (((val / 100) % 10) << 8) | (((val / 10) % 10) << 4) | (val % 10));
}

uint16_t bcdToDec16(uint16_t val)
{
    return(((((val & 0xf000) >> 12) % 10) * 1000) + ((((val & 0x0f00) >> 8) % 10) * 100) + ((((val & 0x00f0) >> 4) % 10) * 10) + ((val & 0x000f) % 10));
}

Upvotes: -1

TomServo
TomServo

Reputation: 7409

The correct conversion functions are:

byte bcdToDec(byte val)
{
  return( (val/16*10) + (val%16) );
}

byte decToBcd(byte val)
{
  return( (val/10*16) + (val%10) );
}

Why does this work? Let's take a single digit 5. In binary, it's

0101 = 5 

Now let's take that same digit, shift it four places to the left by adding four zeroes to the right:

0101 0000 = 50 BCD

That's how BCD works. Since it takes four binary digits to represent the decimal digits 0 through 9, each single decimal digit is represented by four bits. The key is that shifting four places in binary multiplies or divides by 16, so that's the reason for the 16 values in the formulas.

So let's take 96:

0110 = 6
1001 = 9
1001 0110 = 96 BCD

Upvotes: 10

Related Questions