Reputation: 2147
How can I achieve these conversions in C without using sprintf?
20 => 0x20
12 => 0x12
Currently I have:
int year = 12;
int month = 10;
int day = 9;
unsigned char date[3];
date[0] = year & 0xFF;
date[1] = month & 0xFF;
date[2] = day & 0xFF;
date will contain { 0x0C, 0x0A, 0x09 } but I want it to be { 0x12, 0x10, 0x09 }
Upvotes: 0
Views: 15306
Reputation: 715
I found the same difficulty when using a RTCC on my PIC mcu. It somehow is common to store a value from 0to99 in a byte and using the lower and higher nybble as a decimal value.
So the binary nybbles from a char might be:
0001 0010 (Binary BCD coded value)
1 2 (Decimal BCD representation) ^ That would be 12 BCD but 18 Binary
While 00010010 would be 18 when coded in regular binary (https://www.google.nl/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=0b00010010+to+decimal)
I used the code below to fix this.
#define HI_NIBBLE(b) (((b) >> 4) & 0x0F)
#define LO_NIBBLE(b) ((b) & 0x0F)
char BcdToDecimal(char bcd){
return (char)((HI_NIBBLE(bcd)*10)+(LO_NIBBLE(bcd)));
}
char DecimalToBcd(char decimal){
return (char) ((decimal / 10)*16)+(decimal % 10);
}
Upvotes: 0
Reputation: 279255
For the limited 2-digit range you're using:
assert(year >= 0 && year < 100);
date[0] = (year / 10) * 16 + (year % 10);
etc.
You could express it as ((year / 10) << 4) | (year % 10)
if that makes more sense to you.
Upvotes: 5
Reputation: 7072
You just have to retrieve each digit in decimal base en multiply it to its equivalent in hexadecinal.
#include <stdio.h>
int hex(int v){
int total = 0;
int resultbase = 1;
while(v > 0 ){
total += resultbase * (v % 10);
resultbase *= 16;
v /= 10;
}
return total;
}
int main(){
printf ("12 => %x, 20 => %x\n", hex(12), hex(20));
return 0;
}
Upvotes: 6