How to convert a 128-bit integer to a decimal ascii string in C?

前端 未结 7 2212
小蘑菇
小蘑菇 2020-12-14 10:44

I\'m trying to convert a 128-bit unsigned integer stored as an array of 4 unsigned ints to the decimal string representation in C:

unsigned int src[] = { 0x1         


        
7条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-12-14 11:18

    A slow but simple approach is to just printing digits from most significant to least significant using subtraction. Basically you need a function for checking if x >= y and another for computing x -= y when that is the case. Then you can start counting how many times you can subtract 10^38 (and this will be most significant digit), then how many times you can subtract 10^37 ... down to how many times you can subtract 1.

    The following is a full implementation of this approach:

    #include 
    
    typedef unsigned ui128[4];
    
    int ge128(ui128 a, ui128 b)
    {
        int i = 3;
        while (i >= 0 && a[i] == b[i])
            --i;
        return i < 0 ? 1 : a[i] >= b[i];
    }
    
    void sub128(ui128 a, ui128 b)
    {
        int i = 0;
        int borrow = 0;
        while (i < 4)
        {
            int next_borrow = (borrow && a[i] <= b[i]) || (!borrow && a[i] < b[i]);
            a[i] -= b[i] + borrow;
            borrow = next_borrow;
            i += 1;
        }
    }
    
    ui128 deci128[] = {{1u,0u,0u,0u},
                       {10u,0u,0u,0u},
                       {100u,0u,0u,0u},
                       {1000u,0u,0u,0u},
                       {10000u,0u,0u,0u},
                       {100000u,0u,0u,0u},
                       {1000000u,0u,0u,0u},
                       {10000000u,0u,0u,0u},
                       {100000000u,0u,0u,0u},
                       {1000000000u,0u,0u,0u},
                       {1410065408u,2u,0u,0u},
                       {1215752192u,23u,0u,0u},
                       {3567587328u,232u,0u,0u},
                       {1316134912u,2328u,0u,0u},
                       {276447232u,23283u,0u,0u},
                       {2764472320u,232830u,0u,0u},
                       {1874919424u,2328306u,0u,0u},
                       {1569325056u,23283064u,0u,0u},
                       {2808348672u,232830643u,0u,0u},
                       {2313682944u,2328306436u,0u,0u},
                       {1661992960u,1808227885u,5u,0u},
                       {3735027712u,902409669u,54u,0u},
                       {2990538752u,434162106u,542u,0u},
                       {4135583744u,46653770u,5421u,0u},
                       {2701131776u,466537709u,54210u,0u},
                       {1241513984u,370409800u,542101u,0u},
                       {3825205248u,3704098002u,5421010u,0u},
                       {3892314112u,2681241660u,54210108u,0u},
                       {268435456u,1042612833u,542101086u,0u},
                       {2684354560u,1836193738u,1126043566u,1u},
                       {1073741824u,1182068202u,2670501072u,12u},
                       {2147483648u,3230747430u,935206946u,126u},
                       {0u,2242703233u,762134875u,1262u},
                       {0u,952195850u,3326381459u,12621u},
                       {0u,932023908u,3199043520u,126217u},
                       {0u,730304488u,1925664130u,1262177u},
                       {0u,3008077584u,2076772117u,12621774u},
                       {0u,16004768u,3587851993u,126217744u},
                       {0u,160047680u,1518781562u,1262177448u}};
    
    void print128(ui128 x)
    {
        int i = 38;
        int z = 0;
        while (i >= 0)
        {
            int c = 0;
            while (ge128(x, deci128[i]))
            {
                c++; sub128(x, deci128[i]);
            }
            if (i==0 || z || c > 0)
            {
                z = 1; putchar('0' + c);
            }
            --i;
        }
    }
    
    int main(int argc, const char *argv[])
    {
        ui128 test = { 0x12345678, 0x90abcdef, 0xfedcba90, 0x8765421 };
        print128(test);
        return 0;
    }
    

    That number in the problem text in decimal becomes

    11248221411398543556294285637029484152
    

    and Python agrees this is the correct value (this of course doesn't mean the code is correct!!! ;-) )

提交回复
热议问题