Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

-0 not equals 0

I have a function that calculates a value, which is a float:

function crunch (float $a, float $b):float
{
  //do stuff
  return $result;
}

function testSomething (float $a, float $b):bool
{
  //if $result is -0 that returns false
  $result = crunch($a, $b);
  return $result === 0;
}

Why is -0 not equal to 0 and how can if safely check if that number is zero, assuming that 0 should be the same as -0?

UPDATE

Since there was the question for more details. I have a class Vec2 which has x() and y() getters, and a method called cross, which looks like that:

public function cross(Vec2 $vec2):float
{
  return ($this->_x * $vec2->_y) - ($vec2->_x * $this->_y);
}

Running this code:

$cross = $this->cross($d);

results in that debugger output

enter image description here

and $cross === 0 evaluates to false;

like image 405
philipp Avatar asked Jan 03 '23 16:01

philipp


2 Answers

Cast the 0 to float. It's probably failing because 0 as literal is an int, and the result is a float, so === is false because of types.

At least doing something like this, fails like your case (the result is false):

php -r '$a = (float) -0; $b = 0; echo ($a === $b);'

The result is true in this case:

php -r '$a = (float) -0; $b = (float) 0; echo ($a == $b);'
like image 117
monstercode Avatar answered Jan 05 '23 05:01

monstercode


  1. Negative zero isn't a thing. But a negative value smaller than the configured precision for floating point display is.
  2. You can't reliably check direct equivalence between two floats, you can only reasonably check that the difference between two floats is smaller than you care about for a given calculation.

eg:

function float_equiv(float $a, float $b, float $epsilon=NULL) {
    // default to PHP's configured display precision
    $epsilon = $epsilon ?: pow(10, -1*ini_get('precision'));

    if( abs($a - $b) < $epsilon ) {
        return true;
    }
    return false;
}
like image 36
Sammitch Avatar answered Jan 05 '23 06:01

Sammitch