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#.
How to Calculate Average. The average of a set of numbers is simply the sum of the numbers divided by the total number of values in the set. For example, suppose we want the average of 24 , 55 , 17 , 87 and 100 . Simply find the sum of the numbers: 24 + 55 + 17 + 87 + 100 = 283 and divide by 5 to get 56.6 .
Divide the sum of the integers by the number of integers. In our example, the sum of the integers is 24, and there are five integers total, so this is the formula: 24 / 5 = 4.8. For the set of integers 4, 5, 7, 2 and 6, the average is 4.8.
Find the average or mean by adding up all the numbers and dividing by how many numbers are in the set.
Average of two numbers is given by the sum of the two numbers divided by two. The average of two numbers is given by x = (a + b)/2 where x is the average a and b are any two numbers.
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); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With