Is there a more efficient way of expanding a char to an uint64_t?

前端 未结 8 623
星月不相逢
星月不相逢 2021-01-18 06:32

I want to inflate an unsigned char to an uint64_t by repeating each bit 8 times. E.g.

char -> uint64_t
0x00 -> 0x00
0x01 ->         


        
8条回答
  •  清歌不尽
    2021-01-18 07:08

    Two minor optimizations:
    One for testing the bits in the input (a will be destroyed but this doesn't matter)
    The other for shifting the mask.

    static uint64_t inflate(unsigned char a)
    {
        uint64_t mask = 0xFF;
        uint64_t result = 0;
        for (int i = 0; i < 8; i++) {
            if (a & 1)
                result |= mask;
            mask <<= 8;    
            a >>= 1;
        }
    
        return result;
    } 
    

    Maybe you can also replace the 'for (int i = 0; i < 8; i++)'-loop by a 'while (a)'-loop. This works, however, only if the right shift a >>=1 works unsigned (As much as I know C standard allows the compiler to do it signed or unsigned). Otherwise you will have an infinite loop in some cases.

    EDIT:
    To see the result I compiled both variants with gcc -std=c99 -S source.c. A quick glance at the resulting assembler outputs shows that the optimization shown above yields ca. 1/3 viewer instructions, most of them inside the loop.

提交回复
热议问题