This is how to check if variable is a decimal number in PHP (floating point number or numeric string representing a decimal number). The objective is a function which returns true for 5.28 and false for 5.
But how about 5.00 - true or false? There are actually two variants of this problem:
- Check if number is not whole = not integer = has decimal places AND there is at least one non-zero after the decimal point (5.00 is false). We are evaluating the number's value.
- Check if number has decimal places = is written in decimal notation (5.00 is true). We are evaluating the number's format.
Solution depends on variant.
Variant #1: Check that number is not whole
To check if variable's value is not a whole number (5.00 is false), we can use the fmod() function:
function is_not_whole($value) {
if (!is_numeric($value)) {
// Not a number (and not numeric string)
return false;
} elseif (fmod($value, 1) === 0) {
// Has no remainder (is whole number)
return false;
} else {
// Numeric and has remainder
return true;
}
}
Important:
- Do test
is_numeric(). Without that condition, we may get error onfmod()if$valueis not numeric. - Alternatively to
fmod($value, 1) === 0we can usefloor($value) === $value. - But in PHP (unlike some other languages) we can't use the modulo operator
$value % 1 == 0, as that only works with integers, so our $value would be converted to integer and the result would always be no remainder, not decimal.
Variant #2: Check that number has decimal places
To check if variable is numeric and written in decimal notation (5.00 is true), we can treat it as string and try to find the dot:
function has_decimal_point($value) {
if (!is_numeric($value)) {
// Not a number (and not numeric string)
return false;
} elseif (strpos($value, '.') === false) {
// Does not include decimal point
return false;
} else {
// Numeric and has decimal point
return true;
}
}
Important:
- Do test
is_numeric(). Without that condition, any string which includes at least one dot would return true. - Use triple equal in
strpos($value, '.')===false. Do not usestrpos($value, '.')==falseor!strpos($value, '.'). Triple equal ensures our function is true for numeric strings written without integer part, such as.01.
Problems and improvements:
- Our function assumes the decimal separator is dot (
.). If it is something else (like,), we must adjust it. - Our function can incorrectly return true for a numeric string written in scientific notation (e.g. 5.28E+32), which contains the dot, but may or may not be a decimal number. This would need further adjustments, such as checking strpos($value, 'E').
Resources
https://stackoverflow.com/questions/6772603/check-if-number-is-decimal#6772657
https://math.stackexchange.com/questions/3647808/is-5-0-an-integer-or-decimal-number