Search code examples
phporaclevalidationscaleprecision

Validating number precision/scale


How would I validate the precision/scale of a number posted from a form to make sure it can be stored in an Oracle NUMBER column? For example:

<input type="number" name="foo" value="123.45" />

The user submits the form to the PHP backend...

<?php
function isValidNumber($number, $precision, $scale) {
    // ???

    return $isValid;
}

// The precision and scale here are actually dynamic
$isValid = isValidNumber($_POST['foo'], 5, 2);

...where I would like to be able to validate the number without trying to insert/update it in Oracle and handle any precision overflow errors (proactive design, rather than reactive). I have not been able to come up with a method of accurately validating all the various fringe cases (Oracle doesn't produce errors for scale overflow - it just rounds to the maximum, but this rounding could lead to precision overflows, which do produce errors, etc.).


Solution

  • function isValidNumber($number, $precision, $scale) {
        $isValid = false;
        if (is_numeric($number)) {
            $num = round(abs($number), $scale);
            $max = str_repeat('9',$precision - $scale).'.'.str_repeat('9',$scale);
            $isValid = $num <= $max;
        }
        return $isValid;
    }
    

    Output for isValidNumber($number, 5, 2)

    123.456   (valid)
    9999.999  (invalid)
    99999.999 (invalid)
    12.003    (valid)
    999.99    (valid)
    999.999   (invalid)
    1234.5    (invalid)
    

    and finally

    isValid(1234567890123456789012345678.90, 30, 2) == **valid**