C平均值及数值溢出问题

发布时间:2019-08-06 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了C平均值及数值溢出问题脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

两个数的平均值是非常简单的,也就是 (a+b)/2. 但具体到c语言环境里,却有玄机。

Int型大数的平均值问题

对两个Int32类型大数,例如2147483644和2147483646,求平均值。首先在C里用尝试以下算法:

    int a = INT32_MAX - 3; //2147483644
    int b = INT32_MAX - 1; //2147483646
    int val = (a + b) / 2;
    PRintf("average1: %d + %d = %dn", a, b, val);
    //实际打印结果:
    //2147483646 + 2147483644 = -3

显然结果非我们期望的,这是因为 a+b之和超出了Int32的范围。而对于-3的由来,我们可以如下推算:

  1. 假定INT32_MIN = -2147483648, INT32_MAX = 2147483647, 那么:
    INT32_MIN + INT32_MAX == -1
    INT32_MIN == INT32_MAX + 1

  2. 所以 a + b = INT32_MAX - 3 + INT32_MAX - 1

             = INT32_MIN - 1 - 3 + INT32_MAX - 1
             = INT32_MIN + INT32_MAX - 5
             = -1 - 5 = -6
       (a+b)/2 = -6/2 =-3
       

    如何求得正确的平均值呢?

Int型大数求平均值的正确姿势

直接上代码:

  int a = INT32_MAX - 3; //2147483644
  int b = INT32_MAX - 1; //2147483646

  if ((a >0 && b>0) || (a<0 && b<0)){
        val = a + (b-a)/2;
  } else {
      val = (a+b)/2;
  }
  printf("average2: %d + %d = %dn", a, b, val);
  //2147483646 + 2147483644 = 2147483645

主旨思想就是确保计算过程当中,不要有超出int32范围的中间数。

Short型大数的平均值

Short型运算时,会把Short型自动转为Int32型,所以基本上不用考虑溢出的问题了。

short x = INT16_MAX - 3; //32764
short y = INT16_MAX - 1; //32766
short val = (x + y) /2;
printf("(%d + %d)/2 = %dn", x, y, val);
// (32766 + 32764)/2 = 32765

码上传到:https://github.com/JackieGe/c...

脚本宝典总结

以上是脚本宝典为你收集整理的C平均值及数值溢出问题全部内容,希望文章能够帮你解决C平均值及数值溢出问题所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。