I need to check if a parameter (either string or int or float) is a "large" integer. By "large integer" I mean that it doesn't have decimal places and can exceed PHP_INT_MAX. It's used as msec timestamp, internally represented as float.
ctype_digit comes to mind but enforces string type. is_int as secondary check is limited to PHP_INT_MAX range and is_numeric will accept floats with decimal places which is what I don't want.
Is it safe to rely on something like this or is there a better method:
if (is_numeric($val) && $val == floor($val)) {
return (double) $val;
}
else ...
-
have a look at php.net/manual/en/language.types.integer.php#example-71zzlalani– zzlalani2013年12月16日 09:32:18 +00:00Commented Dec 16, 2013 at 9:32
-
2An integer variable can, by definition, not exceed PHP_MAX_INT ...Ja͢ck– Ja͢ck2013年12月16日 09:37:42 +00:00Commented Dec 16, 2013 at 9:37
-
1Binary Calculator ComparisonDaniel W.– Daniel W.2013年12月16日 09:40:00 +00:00Commented Dec 16, 2013 at 9:40
4 Answers 4
I recommend the binary calculator as it does not care about length and max bytes. It converts your "integer" to a binary string and does all calculations that way.
BC math lib is the only reliable way to do RSA key generation/encryption in PHP, and so it can easy handle your requirement:
$userNumber = '1233333333333333333333333333333333333333312412412412';
if (bccomp($userNumber, PHP_INT_MAX, 0) === 1) {
// $userNumber is greater than INT MAX
}
Third parameter is the number of floating digits.
Comments
So basically you want to check if a particular variable is integer-like?
function isInteger($var)
{
if (is_int($var)) {
// the most obvious test
return true;
} elseif (is_numeric($var)) {
// cast to string first
return ctype_digit((string)$var);
}
return false;
}
Note that using a floating point variable to keep large integers will lose precision and when big enough will turn into a fraction, e.g. 9.9999999999991E+36, which will obviously fail the above tests.
If the value exceeds INT_MAX on the given environment (32-bit or 64-bit), I would recommend using gmp instead and persist the numbers in a string format.
8 Comments
echo (isInteger(99999999999999)) ? 1 : 0;99999999999999 is converted to a float with a fraction, e.g. 0.9999999E+XX or something.function isInteger($var)
{
if (is_int($var)) {
return true;
} elseif (is_numeric($var)) {
// will throw warning
if (!gmp_init($var)) {
return false;
} elseif (gmp_cmp($var, PHP_INT_MAX) >0) {
return true;
} else {
return floor($var) == $var;
}
}
return false;
}
Comments
I did at the end of the function to check for numeric data.
return is_numeric($text)&&!(is_int(strpos($text,".",0)));
It will first check if it is numeric then check if there is no decimal in the string by checking if it found a position. If it did the returned position is an int so is_int() will catch it.
(strpos($text,".",0)==FALSE) would also work based on the strpos manual but sometimes the function seems to send nothing at all back like
echo (strpos($text,".",0));
could be nothing and the ==FALSE is needed.