Median calculator

Returns the median of the numbers given

<?php

function median($numbers=array())
{
	if (!is_array($numbers))
		$numbers = func_get_args();
	
	rsort($numbers);
	$mid = (count($numbers) / 2);
	return ($mid % 2 != 0) ? $numbers{$mid-1} : (($numbers{$mid-1}) + $numbers{$mid}) / 2;
}

/*
echo median(array(44,12,34,21,34,55,77,54)); // 39
echo median(1,1,1,2,2,3,3,3); // 2
*/

?>

Usage

As seen in the commented portion of code, this function can take either an array of numbers, or multiple parameters of numbers. *note* returns the average median if there is an even number of numbers going in


Comments

guest
Posted on 19.04.2012 10:03

function median($numbers=array())
{
if (!is_array($numbers))
$numbers = func_get_args();
rsort($numbers);
$mid = (int)(count($numbers) / 2);
return ($mid % 2 != 0) ? $numbers[$mid] : (($numbers[$mid-1]) + $numbers[$mid]) / 2;
}

guest
Posted on 12.01.2011 20:21

Handy function, but it wasn't working correctly for me all of the time. I narrowed it down to two bugs:

1) The modulus (%) function should be applied to the original length of the array, not the length divided in half. Replacing ($mid % 2 != 0) with (count($numbers) % 2 != 0) corrects this. For example, if the original array has 30 elements, $mid will be 15. When $mid is divided by two to get the remainder with %, it will indicate that 15 is odd, when you need it to indicate that 30 is even. An array with 40 elements wouldn't show symptoms, since 20 is still even. The bug, when triggered, causes the wrong operation to be performed during the return statement.

2) The first option for the return statement ($numbers{$mid-1}) always (I think?) calls for an array element with a non-whole number. Original array has 5 elements. The third element should be returned, but half of 5 is 2.5, so the code returns element 1.5 when it should return element 2. Since 1.5 rounds up, this seems to work. I would recommend taking the ceiling of $mid before subtracting one just to be safe. Therefore, replace $numbers{$mid-1} with $numbers{ceil($mid-1} to correct this. Or use floor($mid) and you no longer need to subtract one.

3) Not a bug, but I would have used asort() instead of rsort() just to keep thing simpler to debug. Once the logic is correct, it should work with the array sorted either way.

Thanks for getting me most of the way there!
-Karl

guest
Posted on 20.12.2010 14:11

Doesn't this return the mode, not the median?

guest
Posted on 22.04.2010 07:47

echo median(array(44,12,34,21,34,55,77,54)); // 39

for this example....can u explain how u got 39...
because 3rd element is 34 n 4th is 21
so v add up (34 + 21)/2 = 55/2 = 27.5

Thnx !!

Add your comment