我知道你可以使用这个表将十进制转换为BCD:
0 0000
1 0001
2 0010
3 0011
4 0100
5 0101
6 0110
7 0111
8 1000
9 1001
是否存在此转换的等式或您只需使用该表?我试图为这个转换写一些代码,但我不知道如何为它做数学.建议?
#include <stdint.h>
/* Standard iterative function to convert 16-bit integer to BCD */
uint32_t dec2bcd(uint16_t dec)
{
uint32_t result = 0;
int shift = 0;
while (dec)
{
result += (dec % 10) << shift;
dec = dec / 10;
shift += 4;
}
return result;
}
/* Recursive one liner because that's fun */
uint32_t dec2bcd_r(uint16_t dec)
{
return (dec) ? ((dec2bcd_r( dec / 10 ) << 4) + (dec % 10)) : 0;
}
Run Code Online (Sandbox Code Playgroud)
这是来自微控制器世界....请注意,值在分区中舍入.例如91到BCD将是91/10*16 = 144 + 91%10 = 145.转换为二进制是10010001.
uint8_t bcdToDec(uint8_t val)
{
return ( (val/16*10) + (val%16) );
}
uint8_t decToBcd(uint8_t val)
{
return ( (val/10*16) + (val%10) );
}
Run Code Online (Sandbox Code Playgroud)
通常,当有人说他们想要从十进制转换为BCD时,他们谈论的不只是一个十进制数字.
BCD通常每个字节打包成两个十进制数字(因为0..9适合4位,如图所示),但我认为使用一个字节数组更为自然,每个十进制数字一个.
n位无符号二进制数将适合ceil(n*log_2(10))= ceil(n/log10(2))十进制数字.它也适合ceil(n/3)= floor((n + 2)/ 3))十进制数字,因为2 ^ 3 = 8小于10.
考虑到这一点,这是我如何获得unsigned int的十进制数字:
#include <algorithm>
#include <vector>
template <class Uint>
std::vector<unsigned char> bcd(Uint x) {
std::vector<unsigned char> ret;
if (x==0) ret.push_back(0);
// skip the above line if you don't mind an empty vector for "0"
while(x>0) {
Uint d=x/10;
ret.push_back(x-(d*10)); // may be faster than x%10
x=d;
}
std::reverse(ret.begin(),ret.end());
// skip the above line if you don't mind that ret[0] is the least significant digit
return ret;
}
Run Code Online (Sandbox Code Playgroud)
当然,如果您知道int类型的宽度,则可能更喜欢固定长度数组.如果你能记住第0位是最不重要的并且仅在输入/输出上反向的事实,也没有理由反转.在不使用固定位数的情况下,将最低有效位保持为第一位简化了数字运算操作.
如果要将"0"表示为单个"0"十进制数字而不是空数字字符串(两者都有效),那么您将专门检查x == 0.