Divide a signed integer by a power of 2

前端 未结 3 733
误落风尘
误落风尘 2020-12-17 23:28

I\'m working on a way to divide a signed integer by a power of 2 using only binary operators (<< >> + ^ ~ & | !), and the result has to be round toward 0. I came a

3条回答
  •  猫巷女王i
    2020-12-17 23:50

    OP's reference is of a C# code and so many subtle differences that cause it to be bad code with C, as this post is tagged.

    int is not necessarily 32-bits so using a magic number of 32 does not make for a robust solution.

    In particular (1 << n) + ~0 results in implementation defined behavior when n causes a bit to be shifted into the sign place. Not good coding.

    Restricting code to only using "binary" operators << >> + ^ ~ & | ! encourages a coder to assume things about int which is not portable nor compliant with the C spec. So OP's posted code does not "work" in general, although may work in many common implementations.

    OP code fails when int is not 2's complement, not uses the range [-2147483648 .. 2147483647] or when 1 << n uses implementation behavior that is not as expected.

    // weak code
    int divideByPowerOf2(int x, int n) {
      return (x + ((x >> 31) & ((1 << n) + ~0))) >> n;
    }
    

    A simple alternative, assuming long long exceeds the range of int follows. I doubt this meets some corner of OP's goals, but OP's given goals encourages non-robust coding.

    int divideByPowerOf2(int x, int n) {
      long long ill = x;
      if (x < 0) ill = -ill;
      while (n--) ill >>= 1;
      if (x < 0) ill = -ill;
      return (int) ill;
    }
    

提交回复
热议问题