Unsigned Integer to BCD conversion?

前端 未结 10 1391
囚心锁ツ
囚心锁ツ 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:34

    I know this has been previously answered but I've extended this for unsigned ints of different sizes using a template to build the specific code.

    #include 
    #include 
    
    #include 
    
    #define __STDC_FORMAT_MACROS
    #include 
    
    constexpr int nBCDPartLength = 4;
    constexpr int nMaxSleep = 10000; // Wait enough time (in ms) to check out the boundry cases before continuing.
    
    // Convert from an integer to a BCD value.
    // some ideas for this code are from :
    //  http://stackoverflow.com/questions/1408361/unsigned-integer-to-bcd-conversion
    //  &&
    //  http://stackoverflow.com/questions/13587502/conversion-from-integer-to-bcd
    // Compute the last part of the information and place it into the result location.
    // Decrease the original value to place the next lowest digit into proper position for extraction.
    template R IntToBCD(T nValue) 
    {
        int nSizeRtn = sizeof(R);
        char acResult[nSizeRtn] {};
        R nResult { 0 };
        int nPos { 0 };
    
        while (nValue)
        {
            if (nPos >= nSizeRtn)
            {
                return 0;
            }
    
            acResult[nPos] |= nValue % 10;
            nValue /= 10;
    
            acResult[nPos] |= (nValue % 10) << nBCDPartLength;
            nValue /= 10;
    
            ++nPos;
        }
    
        nResult = *(reinterpret_cast(acResult));
    
        return nResult;
    }
    
    int main(int argc, char **argv)
    {
        //uint16_t nValue { 10 };
        //printf("The BCD for %d is %x\n", nValue, IntToBCD(nValue));
    
        // UINT8_MAX    =   (255)                               - 2 bytes can be held in uint16_t (2 bytes)
        // UINT16_MAX   =   (65535)                             - 3 bytes can be held in uint32_t (4 bytes)
        // UINT32_MAX   =   (4294967295U)                       - 5 bytes can be held in uint64_t (8 bytes)
        // UINT64_MAX   =   (__UINT64_C(18446744073709551615))  - 10 bytes can be held in uint128_t (16 bytes)
    
    
        // Test edge case for uint8
        uint8_t n8Value { UINT8_MAX - 1 };
        printf("The BCD for %u is %x\n", n8Value, IntToBCD(n8Value));
        // Test edge case for uint16
        uint16_t n16Value { UINT16_MAX - 1 };
        printf("The BCD for %u is %x\n", n16Value, IntToBCD(n16Value));
        // Test edge case for uint32
        uint32_t n32Value { UINT32_MAX - 1 };
        printf("The BCD for %u is %" PRIx64 "\n", n32Value, IntToBCD(n32Value));
        // Test edge case for uint64
        uint64_t n64Value { UINT64_MAX - 1 };
        __uint128_t nLargeValue = IntToBCD<__uint128_t, uint64_t>(n64Value);
        uint64_t nTopHalf = uint64_t(nLargeValue >> 64);
        uint64_t nBottomHalf = uint64_t(nLargeValue);
        printf("The BCD for %" PRIu64 " is %" PRIx64 ":%" PRIx64 "\n", n64Value, nTopHalf, nBottomHalf);
    
        usleep(nMaxSleep);
    
        // Test all the values
        for (uint8_t nIdx = 0; nIdx < UINT8_MAX; ++nIdx)
        {
            printf("The BCD for %u is %x\n", nIdx, IntToBCD(nIdx));
        }
    
        for (uint16_t nIdx = 0; nIdx < UINT16_MAX; ++nIdx)
        {
            printf("The BCD for %u is %x\n", nIdx, IntToBCD(nIdx));
        }
    
        for (uint32_t nIdx = 0; nIdx < UINT32_MAX; ++nIdx)
        {
            printf("The BCD for %u is %" PRIx64 "\n", nIdx, IntToBCD(nIdx));
        }
    
        for (uint64_t nIdx = 0; nIdx < UINT64_MAX; ++nIdx)
        {
            __uint128_t nLargeValue = IntToBCD<__uint128_t, uint64_t>(nIdx);
            uint64_t nTopHalf = uint64_t(nLargeValue >> 64);
            uint64_t nBottomHalf = uint64_t(nLargeValue);
            printf("The BCD for %" PRIu64 " is %" PRIx64 ":%" PRIx64 "\n", nIdx, nTopHalf, nBottomHalf);
        }
        return 0;
    }
    

提交回复
热议问题