13

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 ...
3

4 Answers 4

6

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.

Sign up to request clarification or add additional context in comments.

Comments

4

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

Does only work with the enforced cast: echo (isInteger(99999999999999)) ? 1 : 0;
@andig On 32-bit, the scalar 99999999999999 is converted to a float with a fraction, e.g. 0.9999999E+XX or something.
the point is that ctype_digit will fail if the parameter is not a string -> your code doesn't work without the cast. 99... is the largest int I've found ad-hoc that isnt cast to E+XX, but you could just take PHP_INT_MAX+1 instead.... Need to downvote if not fixed??
@andig feel free to edit the cast back in, I'm outside atm; I'll check later why that's actually a requirement.
changing back because ctype_digit($integer) gives false (php.net/ctype_digit)
|
0
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

0

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.

1 Comment

While this code may solve the question, including an explanation of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please edit your answer to add explanations and give an indication of what limitations and assumptions apply.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.