无符号整数到BCD转换?

Bra*_*ble 7 c++ bcd

我知道你可以使用这个表将十进制转换为BCD:

0 0000

1 0001

2 0010

3 0011

4 0100

5 0101

6 0110

7 0111

8 1000

9 1001

是否存在此转换的等式或您只需使用该表?我试图为这个转换写一些代码,但我不知道如何为它做数学.建议?

sch*_*der 8

你知道二进制数字系统,不是吗?

特别是看看这一章.

编辑:另请注意KFro的评论,数字的二进制ASCII表示的低半字节(= 4位)是BCD.这使转换BCD < - > ASCII非常简单,因为您只需要添加/删除前4位:

Number    ASCII Code
0         0011 0000
1         0011 0001
 ...
8         0011 1000
9         0011 1001

  • 还应该注意,数字的ASCII表示也是BCD(故意)......至少是较低的nybble. (3认同)
  • 呃...... KFro.这不是很清楚.你的意思是数字的ASCII表示的低半字节对应于数字的BCD表示吗? (2认同)

Sim*_*ett 7

#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)


nmu*_*hov 6

这是来自微控制器世界....请注意,值在分区中舍入.例如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)

  • 聪明.如果写为return(((val/10)<< 4)+(val%10)),这将更清楚; 因为很明显,乘以16实际上是左移4位,以便将第一个nybble移动到字节中最重要的位置. (2认同)

Jon*_*ehl 5

通常,当有人说他们想要从十进制转换为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.