In C bits, multiply by 3 and divide by 16

后端 未结 5 638
孤独总比滥情好
孤独总比滥情好 2020-12-29 17:46

A buddy of mine had these puzzles and this is one that is eluding me. Here is the problem, you are given a number and you want to return that number times 3 and divided by 1

5条回答
  •  余生分开走
    2020-12-29 18:11

    The Maths

    When you divide a positive integer n by 16, you get a positive integer quotient k and a remainder c < 16:

        (n/16) = k + (c/16).
    

    (Or simply apply the Euclidan algorithm.) The question asks for multiplication by 3/16, so multiply by 3

        (n/16) * 3 = 3k + (c/16) * 3.
    

    The number k is an integer, so the part 3k is still a whole number. However, int arithmetic rounds down, so the second term may lose precision if you divide first, And since c < 16, you can safely multiply first without overflowing (assuming sizeof(int) >= 7). So the algorithm design can be

        (3n/16) = 3k + (3c/16).
    

    The design

    • The integer k is simply n/16 rounded down towards 0. So k can be found by applying a single AND operation. Two further operations will give 3k. Operation count: 3.
    • The remainder c can also be found using an AND operation (with the missing bits). Multiplication by 3 uses two more operations. And shifts finishes the division. Operation count: 4.
    • Add them together gives you the final answer.

    Total operation count: 8.

    Negatives

    The above algorithm uses shift operations. It may not work well on negatives. However, assuming two's complement, the sign of n is stored in a sign bit. It can be removed beforing applying the algorithm and reapplied on the answer.

    • To find and store the sign of n, a single AND is sufficient.
    • To remove this sign, OR can be used.
    • Apply the above algorithm.
    • To restore the sign bit, Use a final OR operation on the algorithm output with the stored sign bit.

    This brings the final operation count up to 11.

提交回复
热议问题