Numeric and percentage deadband calculation Calculate if the value exceeds percentage &lt;> numeric deadbands of the previous value.

The first function is for percentage. It detects if $value is $deadband% greater or less than $previous.

The second is for numeric difference. It detects if the difference between $value and $previous is greater than $deadband.

function percentage_deadband($value,$previous,$deadband)
{
    if($previous==0 || $value==0 || $previous == $value)
    {
        return false; //if previous or value is 0, we can't work. assume false.
    }
    $percentage = $value / $previous * 100;
    if($percentage &gt; 100){
        return $percentage - $deadband &gt; 100;//if percentage - deadband &gt; 100, we know the deadband is exceeded
    }
    if($percentage &lt; 100){
        return 100 - $percentage &gt; $deadband;//if 100 - percentage is greater than deadband, we know the deadband is exceeded
    }
    return false;
}


function numeric_deadband($value,$previous,$deadband)
{
    if($previous==0 || $value==0 || $previous == $value)
    {
        return false;
    }
    if($previous &gt; $value){
        return $previous - $deadband &gt;= $value;
    }else{
        return $value - $previous &gt;= $deadband;
    }
    return false;
}


Testing the functions

$numeric_deadband = 3;
$numeric_set = [
    0=&gt;['value'=&gt;77,'previous'=&gt;80],//true
    1=&gt;['value'=&gt;78,'previous'=&gt;77],//false
    2=&gt;['value'=&gt;81,'previous'=&gt;78],//true
    3=&gt;['value'=&gt;81,'previous'=&gt;81]//false
];
echo '&lt;strong&gt;numeric set:&lt;/strong&gt;&lt;br/&gt;';
foreach($numeric_set as $row)
{

    var_dump(numeric_deadband($row['value'],$row['previous'],$numeric_deadband));
    echo '&lt;br/&gt;';
}

echo '&lt;br/&gt;';

$percentage_deadband = 10;
$percentage_set = [
    0=&gt;['value'=&gt;27,'previous'=&gt;39],//true
    1=&gt;['value'=&gt;39,'previous'=&gt;40],//false
    2=&gt;['value'=&gt;41,'previous'=&gt;28],//true
    3=&gt;['value'=&gt;28,'previous'=&gt;31]//false
];
echo '&lt;strong&gt;percentage set:&lt;/strong&gt;&lt;br/&gt;';
foreach($percentage_set as $row)
{

    var_dump(percentage_deadband($row['value'],$row['previous'],$percentage_deadband));
    echo '&lt;br/&gt;';
}


They seem to work correctly with my small set of test data, but I am not so great with math. I'd love a second opinion.
I'm unclear about what is TRUE and what is FALSE (and how you interpret it).

Is it FALSE = when value is greater than previous by more than deadband?
    (i.e. value &gt; previous + deadband is NOT OK)
    (i.e. value &lt;= previous + deadband is OK)
That's how I did it below, but if you want the opposite, change the "&lt;" sign. 


I would change the two functions in one, and give an extra argument (true for numeric, false for percentage):

    function check_deadband($value,$previous,$deadband,$check_numeric) {
        if ($value &lt;= 0) {
            return false;
        }
        if ($check_numeric) {
           // numeric testing
            $difference=abs($previous-$value);
            return $difference &lt; $deadband;
            // ex. value: 74, previous: 70 =&gt; difference = 4
            // difference: 4 &lt; deadband: 3 =&gt; false, not ok
        } else {
            // percentage testing
            $percentage=abs(($value - $previous) * 100/$previous);
            return $percentage &lt; $deadband;
            // ex. v:111 p:100, (v-p)*100/p:11% &lt; 10% =&gt; false, not ok
        }
    }


You eliminated the previous=0 or previous=value cases in your example, but I didn't understand why (you can put them back).
I also not sure that your percentage formula is corect. If you want the difference in percentage, then (value-previous)*100/previous will give you the right answer. (ex. value = 10, previous=5 => percentage is 100 - correct!)
You can check the function with the following testing code:

    $numeric_deadband = 3;
    $percentage_deadband = 10;

    /// GENERATE RADNOM DATA ex. 5.000 rows
    $rows_nr=5000;
    $min=40;
    $max=80;
    for ($i=0; $i&lt;$rows_nr; $i++) {
        $numeric_set[]=array(
            "value"=&gt;rand($min,$max), 
            "previous" =&gt; rand(40,80));
        $percentage_set[]=array(
            "value"=&gt;rand($min,$max),
            "previous" =&gt; rand(40,80));
    }

    $time=microtime(true); // just for testing purposes
    foreach ($numeric_set as $row) {
        // check NUMERIC set
        // remove echos after testing
        echo "NUMERIC &gt;&gt; value: $row[value] vs previous :".
            "$row[previous] (deadband: $numeric_deadband) =&gt; ";
        echo check_deadband(
            $row["value"],
            $row["previous"],
            $numeric_deadband,
            true)
            ? "true" : "false";
        echo "&lt;br/&gt;";
    } unset($row);

    // CHECK time in miliseconds
    echo "&lt;p&gt;Checking deadband for NUMERIC ($rows_nr rows) took:".
        round((microtime(true)-$time)*1000)." miliseconds&lt;/p&gt;";

    $time=microtime(true);
    foreach ($percentage_set as $row) {
        // check PERCENTAGE set
        // remove echo after testing
        echo "PERCENTAGE &gt;&gt; value: $row[value] vs previous:".
        "$row[previous]  (deadband: $percentage_deadband) =&gt; ";
        echo check_deadband(
            $row["value"],
            $row["previous"],
            $percentage_deadband,
            false)
            ? "true" : "false";
        echo "&lt;br/&gt;";
    } unset($row);

    echo "&lt;p&gt;Checking deadband for PERCENTAGE ($rows_nr rows) took:".
        round((microtime(true)-$time)*1000)." miliseconds&lt;/p&gt;";


Hope this works. Feedback would be appreciated!

EDIT:
Changed the script to detect both above and below deadband changes.