John John
John John

Reputation: 1

Average of an array will fail if I have int.MaxValue in the array

I have defined the following method which calculates the average of an array:

public int AverageOfArray (params int[] arr)
        {
            if (arr.Length > 0)
            {
                double avg = Sum(ints) / arr.Length;
                return (int)avg;
            }
            return 0;
        }

My requirement is that the average should be returned as an integer. When I tried to test this method using the int.MaxValue The unit test will fail. How can I make the test class pass?

UPDATED::-

public int Sum(params int[] arr)
        {
            int total = 0;

            for (int n = 0; n < arr.Length; n++)
            {
                total += arr[n];
            }

            return total;


        }

Upvotes: 0

Views: 172

Answers (2)

Michael Liu
Michael Liu

Reputation: 55409

In the Sum method, the int data type is not sufficient to hold the sum of int.MaxValue / 2 and int.MaxValue / 2 + 4:

     int.MaxValue / 2     = 0x3FFFFFFF
     int.MaxValue / 2 + 4 = 0x40000003
--------------------------------------
Sum: int.MaxValue - 1 + 4 = 0x80000002 (subtract 1 because int.MaxValue is odd)

Because the correct sum exceeds int.MaxValue, it overflows into the sign bit, causing the result to be 232 less than the correct sum (see Two's complement on Wikipedia for more information):

Correct sum:  2147483650
 Actual sum: -2147483646

The actual sum is wrong, so when you divide it by 2, you get the wrong average too. Garbage in, garbage out!

To fix this problem, change the return type of Sum to long, and change the type of the total variable to long as well:

public long Sum(params int[] arr)
{
    long total = 0;
    for (int n = 0; n < arr.Length; n++)
    {
        total += arr[n];
    }
    return total;
}

Now the Sum method returns the correct sum: int.MaxValue + 3 is less than long.MaxValue, so no overflow occurs.

Upvotes: 2

DeanOC
DeanOC

Reputation: 7282

This should work for you

public int AverageOfArray (params int[] arr)
{

    double avg = 0;

    if (arr.Length > 0)
    {
        for (int n = 0; n < arr.Length; n++)
        {
            avg += arr[n]/arr.Length;
        }

    }
    return (int)avg;
}

Upvotes: 0

Related Questions