Average of 3 long integers

.net, c#, long-integer

Solution

This code will work, but isn't that pretty.

It first divides all three values (it floors the values, so you 'lose' the remainder), and then divides the remainder:

long n = x / 3
         + y / 3
         + z / 3
         + ( x % 3
             + y % 3
             + z % 3
           ) / 3

Note that the above sample does not always work properly when having one or more negative values.

As discussed with Ulugbek, since the number of comments are exploding below, here is the current BEST solution for both positive and negative values.

Thanks to answers and comments of Ulugbek Umirov, James S, KevinZ, Marc van Leeuwen, gnasher729 this is the current solution:

static long CalculateAverage(long x, long y, long z)
{
    return (x % 3 + y % 3 + z % 3 + 6) / 3 - 2
            + x / 3 + y / 3 + z / 3;
}

static long CalculateAverage(params long[] arr)
{
    int count = arr.Length;
    return (arr.Sum(n => n % count) + count * (count - 1)) / count - (count - 1)
           + arr.Sum(n => n / count);
}

Problem

I have 3 very large signed integers. ``` long x = long.MaxValue; long y = long.MaxValue - 1; long z = long.MaxValue - 2; ``` I want to calculate their truncated average. Expected average value is `long.MaxValue - 1`, which is `9223372036854775806`. It is impossible to calculate it as: ``` long avg = (x + y + z) / 3; // 3074457345618258600 ``` Note: I read all those questions about average of 2 numbers, but I don't see how that technique can be applied to average of 3 numbers. It would be very easy with the usage of `BigInteger`, but let's assume I cannot use it. ``` BigInteger bx = new BigInteger(x); BigInteger by = new BigInteger(y); BigInteger bz = new BigInteger(z); BigInteger bavg = (bx + by + bz) / 3; // 9223372036854775806 ``` If I convert to `double`, then, of course, I lose precision: ``` double dx = x; double dy = y; double dz = z; double davg = (dx + dy + dz) / 3; // 9223372036854780000 ``` If I convert to `decimal`, it works, but also let's assume that I cannot use it. ``` decimal mx = x; decimal my = y; decimal mz = z; decimal mavg = (mx + my + mz) / 3; // 9223372036854775806 ``` Question: Is there a way to calculate the truncated average of 3 very large integers only with the usage of `long` type? Don't consider that question as C#-specific, just it is easier for me to provide samples in C#.

Original source

Related problems