如何找到两个数字的平均值?

时间:2015-06-26 23:43:03

标签: algorithm math integer average integer-arithmetic

我有一个int代表[0,8 [包围的范围内的数字:

       2      
  1         3


0             4


  7         5
       6

现在我需要找到这样两个数的平均值,所以例如7和0的平均值是7.5,7和2的平均值是0.5,0和4的平均值是2或者6,等等。

我找到了this ("How do you calculate the average of a set of angles?")相关的问题,但它是关于角度的,我不知道它在这里会有什么帮助。还有"How to subtract two unsigned ints with wrap around or overflow",但它是关于减去,而不是寻找平均值。有什么指针吗?

我还有一个wrap函数,如果可以在这里以某种方式使用它:

template <class type>
inline type Wrap(type Value, type Minimum, type Maximum)
{
  Value = ((Value - Minimum) % (Maximum + 1 - Minimum));
  return (Value >= 0 ? Minimum : Maximum + 1) + Value;
}

编辑:尝试更正式地定义规则:

如果abs(a - b) <= 4avg = (a + b) / 2. 否则,avg = (a + b) / 2. + 4; if (avg >= 8) avg -= 8;

6 个答案:

答案 0 :(得分:2)

另一个解决方案是首先将您的数字转换为角度来使用cited的答案:

  1. 将您的数字转换为角度。

    angle_a = a * pi / 4
    angle_b = b * pi / 4
    
  2. 计算每个角度的单位矢量

    unit_a
    unit_b
    
  3. 计算单位向量平均值

    unit_average = (unit_a + unit_b) / 2
    
  4. unit_average的计算角度

    angle_average
    
  5. 将angle_average转换为数字

    number_average = angle_average * 4 / pi
    
  6. 然后 number_average 是我们的答案

答案 1 :(得分:1)

原油但有效:

float foo(int a, int b)
{
  int c;
  if(a>b)
    {
      c=a;
      a=b;
      b=c;
    }

  if( b-a > 3)
    {
      c=a+8;
      a=b;
      b=c;
    }

  float f = 0.5*(a+b);
  if(f>7.6)
    f-=8.0;
  return(f);
}

答案 2 :(得分:1)

我认为第一个回归表达式是你之后:

def av(a,b):
    mi = min(a,b)
    ma = max(a,b)
    if ma - mi > 4:
        return (((mi + 8) + ma) / 2.) % 8
    else:
        return (mi+ma)/2.

mi是两者中的最小值; ma是最大值

答案 3 :(得分:1)

float wAvg(int m, int n)
{
    int minimum = min(m, n);
    int maximum = max(m, n);

    int d1 = minimum + 8 - maximum; // difference between m and n
                                    // when wrapped around
    int d2 = max - min;             // normal difference

    float avg = 0.0f;

    if (d1 < d2)    // if wrapped around distance is shorter than normal distance
    {
        avg = d1 / 2.0f + maximum;

        if (avg >= 8.0f)
            avg -= 8.0f;
    }
    else
    {
        avg = (m + n) / 2.0f;
    }

    return avg;
}

我认为这可能有效

答案 4 :(得分:1)

看到@ Beta&#34;&#34;原油&#34;回答,只是为了好玩:):

float wAvg(int m, int n)
{
    static float results[8][8] =
    {
        {0.0f, 0.5f, 1.0f, 1.5f, 2.0f, 6.5f, 7.0f, 7.5f},
        {0.5f, 1.0f, 1.5f, 2.0f, 2.5f, 3.0f, 7.5f, 0.0f},
        {1.0f, 1.5f, 2.0f, 2.5f, 3.0f, 3.5f, 4.0f, 0.5f},
        {1.5f, 2.0f, 2.5f, 3.0f, 3.5f, 4.0f, 4.5f, 5.0f},
        {2.0f, 2.5f, 3.0f, 3.5f, 4.0f, 4.5f, 5.0f, 5.5f},
        {6.5f, 3.0f, 3.5f, 4.0f, 4.5f, 5.0f, 5.5f, 6.0f},
        {7.0f, 7.5f, 4.0f, 4.5f, 5.0f, 5.5f, 6.0f, 6.5f},
        {7.5f, 0.0f, 0.5f, 5.0f, 5.5f, 6.0f, 6.5f, 7.0f}
    };

    return results[m % 8][n % 8];
}

答案 5 :(得分:0)

大概以下方法会起作用(以与角度相同的方式):

function meanWrappingValue(values: Array<number>, range: number): number {
    return meanAngle(values.map(value => value * (Math.PI * 2) / range)) / (Math.PI * 2) * range;
}

function meanAngle(angles: Array<number>): number {
    let sinSum = angles.reduce((sum, cur) => sum + Math.sin(cur), 0);
    let cosSum = angles.reduce((sum, cur) => sum + Math.cos(cur), 0);
    return normalizeAngle(Math.atan2(sinSum / angles.length, cosSum / angles.length));
}

function normalizeAngle(angle: number): number {
    let range = Math.PI * 2;
    return ((angle % range) + range) % range;
}

在您的情况下,它将是:

let result = meanWrappingValue([7, 2], 8);
console.log(result); // => 0.5