TheCarver
TheCarver

Reputation: 19713

Warning: Division By Zero - Calculating percentages

Okay, before I start, I would like to point out that I know dividing by zero is not good. What I'd like to know is, what's the best way to avoid this.

In my CMS, I'm trying to display the amount of registered users that have recently signed up. The first statistic I'm showing is 'Registered Users Today' and showing whether this value is up or down from yesterdays value, and to show it as a positive/negative percentage.

Reading other questions here on SO, people suggest avoiding the calculation altogether if one of the values equals 0, but surely if there were 0 registered users yesterday, and 20 today, there is a definitive increase that I need to display - I can't just show nothing.

I have created this query:

SELECT
COUNT(CASE WHEN DATEDIFF(HOUR, CURDATE(), created) <= 24 THEN user_id
ELSE NULL END) AS 1day,
COUNT(CASE WHEN DATEDIFF(HOUR, CURDATE(), created) >= 25 AND DATEDIFF(HOUR, CURDATE(), created) <= 48 THEN user_id
ELSE NULL END) AS 1to2days,
... other cases ...
FROM users

This function:

function diff_percent($a, $b) {
    $c = ($a > $b) ? ($a-$b)/$a*-100 : ($b-$a)/$b*100; 
    return $c;
}

And simply call it by:

echo diff_percent($row['1to2days'], $row['1day']);

I could quite easily convert the zero to null using SQL, or I could stop the calculation in the function if a zero is detected, but as I mentioned above, if there were 0 users yesterday, and 20 today, I have to show that there is a considerable rise in users in the last 24-hours. What is the best way to get around this? If todays_users > yesterdays_users but yesterdays_users == 0 do I just show 'Up By 100%'? My math is poor and I'm very confused - please help.

Upvotes: 2

Views: 3647

Answers (2)

Flight Odyssey
Flight Odyssey

Reputation: 2287

Why don't you try finding percentages using the midpoint method ( http://www.econport.org/content/handbook/Elasticity/Calculating-Percentage-Change.html), either for all cases or just when the initial value is 0? Basically, instead of dividing the change by the initial value (like a normal percentage), divide the change by the average of the initial and final values.

If you use the midpoint method, you will only get a divide by zero error if both values are zero (assuming we're not dealing with negative numbers) which you can treat as a special case and just show 0%, since there was no change.

Upvotes: 0

Ed Heal
Ed Heal

Reputation: 60007

"Okay, before I start, I would like to point out that I know dividing by zero is not good. What I'd like to know is, what's the best way to avoid this."

  • Do not divide by Zero!

Add extra checks before doing the calculation and if zero is encountered handle that appropriateley. i.e. Display a different message instead of the percentage.

Upvotes: 3

Related Questions