Re: [PHP] variable type - conversion/checking

[email protected] (Andrew Ballard)
Newsgroups php.general
Message-ID <CAC1b6RsMPrMqts_3tqPY5akBfpca1dt1cKQKjbv99q=VZth_nQ@mail.gmail.com>
On Sat, Mar 16, 2013 at 12:21 PM, Ashley Sheridan
<[email protected]> wrote:
>
> On Sat, 2013-03-16 at 11:46 -0400, Andrew Ballard wrote:
>
> On Mar 16, 2013 6:14 AM, "Ashley Sheridan" <[email protected]> wrote:
> >
> > On Fri, 2013-03-15 at 22:32 -0400, Andrew Ballard wrote:
> >>
> >> > Guess regex are the only useful solution here. When you consider to use
> >> > built-in functions, just remember, that for example '0xAF' is an
> integer
> >> > too, but '42.00' isn't.
> >>
> >> Shoot...I hadn't considered how PHP might handle hex or octal strings
> when
> >> casting to int. (Again, not in front of a computer where I can test it
> >> right now. )
> >>
> >> Regexes have problems with more than 9 digits for 32-bit ints. I guess to
> >> some degree it depends on how likely you are to experience values that
> >> large.
> >>
> >> Andrew
> >
> >
> > Do they? Regex's deal with strings, so I don't see why they should have
> such issues. I've certainly never come across that problem, or heard of it
> before.
> >
> > Thanks,
> > Ash
> > http://www.ashleysheridan.co.uk
> >
> >
>
> Sure. If the string is nine or fewer digits, they can all be 0-9. If it is
> 10 digits, the first digit can only be 1-2. If it's 1, the remaining nine
> digits can still be 0-9, but if the first digit is 2, the second digit can
> only be 0-1. If the second digit is 0, the remaining eight digits can still
> be 0-9, but if it is 1, the third digit can only be 0-4. If the third digit
> is 0-3, the remaining seven digits can still be 0-9, but if it is 4, the
> fourth digit can only be 0-7.
>
> This pattern would continue for each of the remaining digits. Hopefully you
> get the idea. When you get to the final digit, its range depends not only
> on the nine preceding digits, but also the sign. If this is 64-bit, that
> adds even more wrinkles (including being aware of whether your
> implementation supports 64-bit ints). It may be possible to do with regular
> expressions, but it would definitely be complex and probably a time sink.
>
> As I said, if you KNOW you won't be dealing with integers that are more
> than nine digits, the regex should work fine.
>
> Remember, the OP didn't ask if it was an integer in the realm of infinite
> pure integers; he asked how to tell if a string was a number that could be
> converted to an int (presumably without loss).
>
> Andrew
>
>
> Ah, I see. I think that's not an issue as such with regular expressions
> having problems, more that bit limitations has a problem with numbers!

ANY computer system is going to have limitations with numbers -- you
can't store infinity in a finite system. LOL

> Bearing that in mind, this does the trick:
>
> $string1 = '999999999';
> $string2 = '9999999999';
> $string3 = '999999999999999999999999999999';
>
> var_dump($string === (intval($string1).''));
> var_dump($string === (intval($string2).''));
> var_dump($string === (intval($string3).''));

That's the same thing I posted, just different syntax. You are still
converting the string to an int, converting the int back to a string,
and comparing the resulting value to the original string using the
identical (===) operator. Depending on one's needs, it could be
tweaked a little to handle leading/trailing spaces, leading zeroes,
etc.

function is_int_hiding_as_string($value)
{

    if (is_string($value)) {

        // remove any spaces around the value.
        $value = trim($value);

        // check for a sign :-)
        $sign = (substr($value, 0, 1) === '-') ? '-' : '';

        // strip off the sign, any additional leading spaces or zeroes
        $value = ltrim($value, ' 0-');

        // I didn't strip off trailing zeroes after the decimal because
        // I consider that a loss of precision, but you could do so
        // if necessary.

        return ($value === $sign . (int)$value);

    }

    return false;
}


> I'm getting the expected results on my machine (32-bit) but a 64-bit machine would get the correct results for larger numbers.


As I understood the original post, these ARE the correct results on
ANY system. If the string value can be safely converted to an int *in
the environment under which the script is executing* without loss of
precision, this will return true; if it cannot, it returns false.


Sorry for getting carried away, but it is SO much easier to respond on
an actual keyboard than my phone. :-)

Andrew
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.