C++ fast division/mod by 10^x

后端 未结 10 624
我寻月下人不归
我寻月下人不归 2020-12-03 05:13

In my program I use a lot of integer division by 10^x and integer mod function of power 10.

For example:

unsigned __int64 a = 12345;
a = a / 100;
...         


        
10条回答
  •  再見小時候
    2020-12-03 05:28

    On a different note instead, it might make more sense to just write a proper version of Div#n# in assembler. Compilers can't always predict the end result as efficiently (though, in most cases, they do it rather well). So if you're running in a low-level microchip environment, consider a hand written asm routine.

    #define BitWise_Div10(result, n) {      \
        /*;n = (n >> 1) + (n >> 2);*/           \
        __asm   mov     ecx,eax                 \
        __asm   mov     ecx, dword ptr[n]       \
        __asm   sar     eax,1                   \
        __asm   sar     ecx,2                   \
        __asm   add     ecx,eax                 \
        /*;n += n < 0 ? 9 : 2;*/                \
        __asm   xor     eax,eax                 \
        __asm   setns   al                      \
        __asm   dec     eax                     \
        __asm   and     eax,7                   \
        __asm   add     eax,2                   \
        __asm   add     ecx,eax                 \
        /*;n = n + (n >> 4);*/                  \
        __asm   mov     eax,ecx                 \
        __asm   sar     eax,4                   \
        __asm   add     ecx,eax                 \
        /*;n = n + (n >> 8);*/                  \
        __asm   mov     eax,ecx                 \
        __asm   sar     eax,8                   \
        __asm   add     ecx,eax                 \
        /*;n = n + (n >> 16);*/                 \
        __asm   mov     eax,ecx                 \
        __asm   sar     eax,10h                 \
        __asm   add     eax,ecx                 \
        /*;return n >> 3;}*/                    \
        __asm   sar     eax,3                   \
        __asm   mov     dword ptr[result], eax  \
    }
    

    Usage:

    int x = 12399;
    int r;
    BitWise_Div10(r, x); // r = x / 10
    // r == 1239
    

    Again, just a note. This is better used on chips that indeed have really bad division. On modern processors and modern compilers, divisions are often optimized out in very clever ways.

提交回复
热议问题