代码之家  ›  专栏  ›  技术社区  ›  Matt Brailsford

如何在C中将二进制编码的十进制转换为int++

  •  0
  • Matt Brailsford  · 技术社区  · 7 年前

    uint16_t hex = 0x80;
    uint8_t val = ???; // Needs to be 80
    

    只有十六进制数字的数字永远不会出现。一、 e.输入仅由十进制数字组成。
    E、 g.0x08、0x09、0x10、0x11、0x12等。

    4 回复  |  直到 7 年前
        1
  •  4
  •   leyanpan    7 年前

    一个简单的实现如下:

    int from_hex(uint16_t h)
    {
        int d = 0;
        int power = 1;
        while (h)
        {
            // assert(h % 16 < 10)
            d += h % 16 * power;
            h /= 16;
            power *= 10;
        }
        return d;
    }
    

    多亏了 Minor Threat 对于以下各项:

    int from_hex(uint16_t h)
    {
        int d = 0;
        int power = 1;
        while (h)
        {
            // assert(h % 16 < 10)
            d += (h & 15) * power;
            h >>= 4;
            power *= 10;
        }
        return d;
    }
    

    我很高兴知道我的代码是否有问题

        2
  •  2
  •   4386427    7 年前

    既然你说十六进制数从不包含“a”、“b”等,那么这段代码应该做到这一点:

    #include <iostream>
    
    int main() {
        uint16_t in = 0x4321;
    
        int t = (1000 * ((in & 0xf000) / (16*16*16))) + 
                 (100 * ((in & 0xf00) / (16*16))) + 
                  (10 * ((in & 0xf0) / 16)) + 
                   (1 * ((in & 0xf) / 1));
        std::cout << t << std::endl;
        return 0;
    }
    

    4321
    

    解释

    =0xWZYX中的16位十六进制数计算如下:

    in = W*16^3 + Z*16^2 + Y*16^1 + X*16^0 (or just W*16^3 + Z*16^2 + Y*16^1 + X)
    

    in & 0xf000 you get 0xW000
    

    执行时

    0xW000 / 16^3 you get 0x000W or just W
    

    执行时

    1000 * W you get W000 decimal
    

    然后对每个数字重复该模式。

    使用shift的替代实现

    #include <iostream>
    
    int main() {
        uint16_t in = 0x9321;
    
        int t = (1000 * ((in & 0xf000) >> 12)) + 
                 (100 * ((in & 0xf00) >> 8)) + 
                  (10 * ((in & 0xf0) >> 4)) + 
                   (1 * ((in & 0xf) >> 0));
        std::cout << t << std::endl;
        return 0;
    }
    

    对于16位无符号整数,可以写出四行。然而,如果您希望为较大的无符号int使用类似的函数,那么最好执行循环以使代码更加紧凑和可维护。

    #include <iostream>
    
    int64_t directHexToDec(uint64_t in)
    {
        int64_t res = 0;
        uint64_t mask = 0xf;
        uint64_t sh = 0;
        uint64_t mul = 1;
        for (int i=0; i<16; ++i)
        {
            res += mul * ((in & mask) >> sh);
            mul *= 10;
            mask <<= 4;
            sh += 4;
        }
        return res;
    }
    
    int main() {
        uint64_t in = 0x987654321;
    
        int64_t t = directHexToDec(in);
        std::cout << t << std::endl;
        return 0;
    }
    

    输出

    987654321
    
        3
  •  1
  •   Ervin Szilagyi    7 年前

    0x0A 0X0B , ... 价值观

    uint16_t val = 0x80;
    std::stringstream stream;
    stream << std::hex << val;
    std::string resultStr(stream.str());
    // In case of 0xYY hex value be carefull that YY fits into an uint8_t, 
    // otherwise  this will overflow
    uint8_t result = static_cast<uint8_t>(std::stoi(resultStr));
    
        4
  •  1
  •   sergej    7 年前

    这应该适用于十六进制<=0x99:

    #include <iostream>
    
    unsigned int foo(unsigned int hex)
    {
        return  hex - (hex >> 4) * 6;
    }
    
    /* Test */
    int main()
    {
        unsigned int vals[] = {0x08, 0x09, 0x10, 0x11, 0x12, 0x80};
    
        for (int i = 0; i < sizeof(vals) / sizeof(vals[0]); i++)
            std::cout << foo(vals[i]) << std::endl;
    
        return 0;
    }
    

    8
    9
    10
    11
    12
    80