Search code examples
algorithmmathintegeraverageinteger-arithmetic

How to find average of two numbers that wrap around?


I have an int that represents numbers in the range [0, 8[ that wraps around:

       2      
  1         3


0             4


  7         5
       6

Now I need to find the average of two numbers like this, so that for example the average of 7 and 0 would be 7.5, the average of 7 and 2 would be 0.5, the average of 0 and 4 would be 2 or 6, etc.

I found this ("How do you calculate the average of a set of angles?") related question, but it's about angles and I don't see how it could help here. There's also "How to subtract two unsigned ints with wrap around or overflow" but it's about subtracting, and not about finding an average. Any pointers?

I also have a wrap function, if that can be utilized here somehow:

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

Edit: Trying to define the rules more formally:

If abs(a - b) <= 4 then avg = (a + b) / 2..
Otherwise, avg = (a + b) / 2. + 4; if (avg >= 8) avg -= 8;.


Solution

  • I think the first return expression is what you're after:

    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 is the minimum of the two; ma is the max.