Search code examples
phpyii2comparison-operators

Yii2 less than evaluates to true at equal


I have a function to check if an attribute value is smaller then another one:

public function getFnGminGrFnotKlFnut() {
    if ($this->FnGmin) {
        return $this->FnGmin > $this->fnot || $this->FnGmin < $this->fnut ? ['class' => 'danger'] : [];
    } else {
        return [];
    }
}

View:

[
    'attribute' => 'FnGmin',
    'contentOptions' => function ($model) {return $model->fnGminGrFnotKlFnut;},
],

$this->FnGmin < $this->fnut evaluates to true however if I'm printing the values they are equals. E.g. FnGmin = 8.37 and fnut = 8.37 and it's red! However sometimes the function returns correct evaluation! By FnGmin = 8.38 and fnut = 8.38 it's not red! There are no more hidden decimal places and roundings. What is going on? Can you please help me? I would greatly appreciate that!


Solution

  • I guess this is because of the floating point precision of php. I guess you have calculated some values used.

    for example:

    $x = 8 - 6.4;  // which is equal to 1.6
    $y = 1.6;
    var_dump($x == $y); // is not true
    //PHP thinks that 1.6 (coming from a difference) is not equal to 1.6. To make it work, use round()
    var_dump(round($x, 2) == round($y, 2)); // this is true
    

    there are several answers already:

    PHP - Getting a float variable internal value

    Set precision for a float number in PHP

    In your case use something like this:

    // set some wanted floating point precision which is higher that your used float numbers e.g. 3 
    $precision = 3;
    
    
    return round($this->FnGmin, $precision) > round($this->fnot, $precision)  || round($this->FnGmin, $precision)  < round($this->fnut, $precision) ? ['class' => 'danger'] : [];