什么是找到两个值的平均值的正确方法? [英] What is the right way to find the average of two values?

查看:117
本文介绍了什么是找到两个值的平均值的正确方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近才知道,整数溢出是C中的未定义行为(方的问题 - 是它也UB在C ++中)

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

经常在C语言编程,你需要找到两个值 A B 的平均值。但是这样做(A + B)/ 2 可导致溢出和不确定的行为。

Often in C programming you need to find the average of two values a and b. However doing (a+b)/2 can result in overflow and undefined behavior.

所以我的问题是 - 什么是找到两个值的平均值的正确方法 A B 中C 3

So my question is - what is the right way to find the average of two values a and b in C?

推荐答案

与<帮助href=\"https://www.securecoding.cert.org/confluence/display/sec$c$c/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow\"相对=nofollow>安全编码

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;
}

附录

感谢@chux您指出的四舍五入问题。下面是对正确的舍入测试版本...

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;
    }
}

这篇关于什么是找到两个值的平均值的正确方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆