What is the right way to find the average of two values?

后端 未结 8 1171
北荒
北荒 2021-02-19 00:58

I recently learned that integer overflow is an undefined behavior in C (side question - is it also UB in C++?)

Often in C programming you need to find the average of two

8条回答
  •  花落未央
    2021-02-19 01:20

    With help from Secure Coding

    if (((si_b > 0) && (si_a > (INT_MAX - si_b))) ||
        ((si_b < 0) && (si_a < (INT_MIN - si_b))))
    {
      /* will overflow, so use difference method */
      return si_b + (si_a - si_b) / 2;
    } 
    else
    {
     /* the addition will not overflow */
      return (si_a + si_b) / 2;
    }
    

    ADDENDUM

    Thanks to @chux for pointing out the rounding problem. Here's a version that's tested for correct rounding...

    int avgnoov (int si_a, int si_b)
    {
        if ((si_b > 0) && (si_a > (INT_MAX - si_b)))
        {
          /* will overflow, so use difference method */
          /* both si_a and si_b > 0; 
              we want difference also > 0
              so rounding works correctly */
          if (si_a >= si_b)
            return si_b + (si_a - si_b) / 2;
          else
            return si_a + (si_b - si_a) / 2;
        } 
        else if ((si_b < 0) && (si_a < (INT_MIN - si_b)))
        {
          /* will overflow, so use difference method */
          /* both si_a and si_b < 0; 
              we want difference also < 0
              so rounding works correctly */
          if (si_a <= si_b)
            return si_b + (si_a - si_b) / 2;
          else
            return si_a + (si_b - si_a) / 2;
        }
        else
        {
         /* the addition will not overflow */
          return (si_a + si_b) / 2;
        }
    }
    

提交回复
热议问题