C quick calculation of next multiple of 4?

前端 未结 7 1878
无人共我
无人共我 2020-12-15 05:04

What\'s a fast way to round up an unsigned int to a multiple of 4?

A multiple of 4 has the two least significant bits 0, right? So I could

相关标签:
7条回答
  • 2020-12-15 05:18

    If by "next multiple of 4" you mean the smallest multiple of 4 that is larger than your unsigned int value myint, then this will work:

    (myint | 0x03) + 1;
    
    0 讨论(0)
  • 2020-12-15 05:20

    If you want the next multiple of 4 strictly greater than myint, this solution will do (similar to previous posts):

    (myint + 4) & ~3u
    

    If you instead want to round up to the nearest multiple of 4 (leaving myint unchanged if it is a multiple of 4), this should work:

    (0 == myint & 0x3) ? myint : ((myint + 4) & ~3u);
    
    0 讨论(0)
  • 2020-12-15 05:28

    myint = (myint + 4) & 0xffffffc

    This is assuming that by "next multiple of 4" that you are always moving upwards; i.e. 5 -> 8 and 4 -> 8.

    0 讨论(0)
  • 2020-12-15 05:31
    (myint + 3) & ~0x03
    

    The addition of 3 is so that the next multiple of 4 becomes previous multiple of 4, which is produced by a modulo operation, doable by masking since the divisor is a power of 2.

    0 讨论(0)
  • 2020-12-15 05:31

    (myint + 4) & 0xFFFC

    0 讨论(0)
  • 2020-12-15 05:42

    I assume that what you are trying to achieve is the alignment of the input number, i.e. if the original number is already a multiple of 4, then it doesn't need to be changed. However, this is not clear from your question. Maybe you want next multiple even when the original number is already a multiple? Please, clarify.

    In order to align an arbitrary non-negative number i on an arbitrary boundary n you just need to do

    i = i / n * n;
    

    But this will align it towards the negative infinity. In order to align it to the positive infinity, add n - 1 before peforming the alignment

    i = (i + n - 1) / n * n;
    

    This is already good enough for all intents and purposes. In your case it would be

    i = (i + 3) / 4 * 4;
    

    However, if you would prefer to to squeeze a few CPU clocks out of this, you might use the fact that the i / 4 * 4 can be replaced with a bit-twiddling i & ~0x3, giving you

    i = (i + 3) & ~0x3;
    

    although it wouldn't surprise me if modern compilers could figure out the latter by themselves.

    0 讨论(0)
提交回复
热议问题