找到两个值的平均值的正确方法是什么?

 萱璇妍幽 发布于 2023-01-01 14:36

我最近了解到整数溢出是C中未定义的行为(侧面问题 - 它是否也是C++中的UB?)

经常在C语言编程,你需要找到两个值的平均值ab.但是,这样做(a+b)/2会导致溢出和未定义的行为.

所以我的问题是-什么是找到两个值的平均值的正确方法a,并b用C?

2 个回答
  • (a >> 1) + (b >> 1) + (((a & 1) + (b & 1)) >> 1)
    

    c int数学中的shift语句(x >> i)等于2除以i的幂.所以声明(a >> 1)+(b >> 1)与a/2 + b/2相同.但是,也需要添加数字截断部分的平均值.该值可以通过掩蔽(a&1),添加((a&1)+(b&1))和除(((a&1)+(b&1))>> 1)来获得.平均值变为(a >> 1)+(b >> 1)+(((a&1)+(b&1))>> 1)

    注意:使用>>和&而不是/和%作为除法和余数运算符的原因之一是效率.

    2023-01-01 14:38 回答
  • 在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;
    }
    

    附录

    感谢@chux指出舍入问题.这是一个经过正确舍入测试的版本......

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

    2023-01-01 14:38 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有