Unsigned Integer to BCD conversion?

前端 未结 10 1356
囚心锁ツ
囚心锁ツ 2020-12-11 05:01

I know you can use this table to convert decimal to BCD:

0 0000

1 0001

2 0010

3 0011

4 0100

5 0101

6 01

10条回答
  •  一生所求
    2020-12-11 05:18

    Usually when someone says they want to convert from decimal to BCD, they're talking about more than one decimal digit.

    BCD is often packed into two decimal digits per byte (because 0..9 fit in 4 bits, as you've shown), but I think it's more natural to use an array of bytes, one per decimal digit.

    An n-bit unsigned binary number will fit into ceil(n*log_2(10)) = ceil(n/log10(2)) decimal digits. It will also fit in ceil(n/3) = floor((n+2)/3)) decimal digits, since 2^3=8 is less than 10.

    With that in mind, here's how I'd get the decimal digits of an unsigned int:

    #include 
    #include 
    
    template 
    std::vector bcd(Uint x) {  
      std::vector 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;
    }
    

    Of course, if you know the width of your int type, you may prefer fixed length arrays. There's also no reason to reverse at all if you can remember the fact that the 0th digit is the least significant and reverse only on input/output. Keeping the least significant digit as the first simplifies digit-wise arithmetic ops in the case that you don't use a fixed number of digits.

    If you want to represent "0" as the single "0" decimal digit rather than the empty digit-string (either is valid), then you'd check specifically for x==0.

提交回复
热议问题