0

I'm getting a division by zero error on this line of code:

$ratio['p{W}'] = ($ratio['{W}'] === 0) ? 0 : ($colorTotal === 0) ? 0 : ($ratio['{W}'] / $colorTotal) * 100;

I've tested the above with:

echo '$ratio[{W}]:'.$ratio['{W}'].', $colorTotal:'.$colorTotal;

if($ratio['{W}'] === 0) {
    echo('$ratio[{W}]: zero');
}
else {
    echo('$ratio[{W}]: not zero');
}

if($colorTotal === 0) {
    echo('$colorTotal: zero');
}
else {
    echo('$colorTotal: not zero');
}

and the results are:

[01-Jul-2015 17:40:26 UTC] $ratio[{W}]:0, $colorTotal:0

[01-Jul-2015 17:40:26 UTC] $ratio[{W}]: zero

[01-Jul-2015 17:40:26 UTC] $colorTotal: zero

It seems I should never reach this point ($ratio['{W}'] / $colorTotal) in the code since the previous criteria is 0 in the checks but it seems to reach it? How can I prevent this error?

Nisse Engström
  • 4,738
  • 23
  • 27
  • 42
Howard
  • 3,648
  • 13
  • 58
  • 86

3 Answers3

3

Ternary operators are left-associative in PHP. Your code is equivalent to:

$ratio['p{W}'] = (($ratio['{W}'] === 0) ? 0 : ($colorTotal === 0)) ? 0 : ($ratio['{W}'] / $colorTotal) * 100;

meaning that ($ratio['{W}'] === 0) ? 0 : ($colorTotal === 0) evaluates first. The result of this is either 0 or true, meaning that the true part of the second ternary will always execute.

It looks to me like you probably want to make the whole expression right-associative:

$ratio['p{W}'] = ($ratio['{W}'] === 0) ? 0 : (($colorTotal === 0) ? 0 : ($ratio['{W}'] / $colorTotal) * 100);
ElGavilan
  • 6,610
  • 16
  • 27
  • 36
  • You have to place the semicolon on the outside of the brackets but I'll choose yours as the answer. – Howard Jul 01 '15 at 18:04
  • That's what you get overusing ternary operators... 1 nesting level, and yet you're not sure exactly what happens... – Laurent S. Jul 01 '15 at 18:07
  • To be honest it's more due to my lack of understanding of ternary operators and the order of operation that was happening more than anything. I learned something new today. – Howard Jul 01 '15 at 18:09
0

I'll start out by adding parenthesis around your ternaries, since I'm afraid ElGavilan is right. Your one-liner is quite ugly to read, and refers to code we don't have, which means we can't test your code.

I like ternaries... but not that way !

Balmipour
  • 2,985
  • 1
  • 24
  • 28
  • parent::p is just echo I changed it to echo so it's easy to understand. – Howard Jul 01 '15 at 17:57
  • Plus one for *I like ternaries... but not that way*.. You are right, the ternary operator should be used to make the code *more* readable and not to make it *less* readable. – hek2mgl Jul 01 '15 at 18:01
0
$ratio['p{W}'] = ($ratio['{W}'] === 0) ? 0 : ($colorTotal === 0) ? 0 : ($ratio['{W}'] / $colorTotal) * 100;

($ratio['{W}'] === 0) means $ratio['{W}'] is false then the false code ($colorTotal === 0) execute in the both cases ($ratio['{W}'] === 0) & ($colorTotal === 0) value became 0. Same for last case division case 0/0.

Asif Mushtaq
  • 3,658
  • 4
  • 44
  • 80