how to calculate (a times b) divided by c only using 32-bit integer types even if a times b would not fit such a type

前端 未结 7 1782
一生所求
一生所求 2021-01-06 00:59

Consider the following as a reference implementation:

/* calculates (a * b) / c */
uint32_t muldiv(uint32_t a, uint32_t b, uint32_t c)
{
    uint64_t x = a;
         


        
相关标签:
7条回答
  • 2021-01-06 01:25

    You can first divide a by c and also get the reminder of the division, and multiply the reminder with b before dividing it by c. That way you only lose data in the last division, and you get the same result as making the 64 bit division.

    You can rewrite the formula like this (where \ is integer division):

    a * b / c =
    (a / c) * b =
    (a \ c + (a % c) / c) * b =
    (a \ c) * b + ((a % c) * b) / c
    

    By making sure that a >= b, you can use larger values before they overflow:

    uint32_t muldiv(uint32_t a, uint32_t b, uint32_t c) {
      uint32_t hi = a > b ? a : b;
      uint32_t lo = a > b ? b : a;
      return (hi / c) * lo + (hi % c) * lo / c;
    }
    

    Another approach would be to loop addition and subtraction instead of multiplying and dividing, but that is of course a lot more work:

    uint32_t muldiv(uint32_t a, uint32_t b, uint32_t c) {
      uint32_t hi = a > b ? a : b;
      uint32_t lo = a > b ? b : a;
      uint32_t sum = 0;
      uint32_t cnt = 0;
      for (uint32_t i = 0; i < hi; i++) {
        sum += lo;
        while (sum >= c) {
          sum -= c;
          cnt++;
        }
      }
      return cnt;
    }
    
    0 讨论(0)
提交回复
热议问题