6

I have a unit test that is used to test variable conversions from string to integer. So far it's good, except for the last one.

$_GET['name'] = '42000000000000000000000000000000000000';
$text = $input->get( 'name', Convert::T_INTEGER );
$this->assertEquals( 92233720368547755807, $text );

The expectancy is (which is confirmed by the test itself), is that the large value, when converted from string to integer using intval() causes an overflow which defaults to the largest integer value that php can handle on my system. Yet, it still fails:

Failed asserting that <integer:92233720368547755807> matches expected <double:9.2233720368548E+19>

And when I try to force the expected number into an integer:

$this->assertEquals( intval(92233720368547755807), $text );

I get this:

Failed asserting that <integer:92233720368547755807> matches expected <integer:0>

Which is what the test run literally right before this one tests for...

Relevant code:

public function get( $name, $type = null )
{
    $value = $_GET['value'];
    if( !is_null( $type ) )
        $value = Convert::to( $value, $type );
    return $value;
}

And

public static function to( $value, $type )
{
    switch( $type )
    {
        case self::T_INTEGER:
            return intval( $value );
        default:
            return null;
    }
}

So the question is this: How do I get this test to return positive?

2
  • 2
    PS: I'd suggest to use the type casting ( "(int)" ), instead of intval! It's much faster and has the same behavior as intval() in most cases. Commented Sep 3, 2011 at 16:13
  • Thanks for the suggestion, but until this becomes an actual bottleneck I think it'll be fine for now. Just trying to avoid pre-optimization is all. I'll keep it in mind though! Commented Sep 3, 2011 at 16:31

3 Answers 3

8

Use the PHP_INT_MAX constant:

$this->assertEquals( PHP_INT_MAX, $text );

This will fix your problem, AND make your test more portable (e.g. it will work on 32bit systems too).

PHP_INT_MAX's value is the larger representable int by your PHP build.

See http://php.net/manual/en/reserved.constants.php

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

1 Comment

Excellent points, sir! And yeah, this does solve the problem in more ways than one, so I'll accept this as the answer. Thanks!
4

You have an extra 5 in your number. This:

92233720368547755807

Should be this:

9223372036854775807

1 Comment

Ehehe. Oops, didn't realize that. Thanks for the catch!
-1

Your problem is, that ever number higher to INT_MAX gets converted to float, which loses precision. If you compare it to String, it always returns false.

Please use bcmath functions for dealing with such large numbers.

4 Comments

When it's meant to be an int, INT_MAX is fine. When it's meant to be a float, it's already been planned to use bcmath to keep the needed precision. This could have been stuck as a comment btw.
Oh? Really? A question that said nothing about using floats and everything about keeping with integers (and thus also testing their overflow) was unclear?
How do I get this test to return positive? Remove everthing and return true;
Yes, but in this case it is just an example to support my thesis that question was unclear.

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.