在PHP中测试整数溢出

4

我有一个单元测试,用于测试从字符串到整数的变量转换。目前为止一切正常,除了最后一个。

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

预期的结果是(这已经被测试所证实),将大值转换为整数使用intval()函数会导致溢出,这会默认转换为php系统可以处理的最大整数值。然而,它仍然失败:
Failed asserting that <integer:92233720368547755807> matches expected <double:9.2233720368548E+19>

当我试图将期望的数字转换为整数时:

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

I get this:

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

这个测试运行的就是上一个测试所测试的内容...

相关代码:

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

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

那么问题就在于:我该如何使这个测试的结果为阳性?

2
建议使用类型转换(“(int)”)而不是intval!它更快,并且在大多数情况下具有与intval()相同的行为。 - ItalyPaleAle
谢谢你的建议,但在这成为实际瓶颈之前,我认为现在还可以。只是想避免过早优化而已。不过我会记住的! - Mike S
3个回答

8
使用PHP_INT_MAX常量:
$this->assertEquals( PHP_INT_MAX, $text );

这将解决你的问题,并使你的测试更加通用(例如,在32位系统上也可以工作)。
PHP_INT_MAX的值是由你的PHP构建表示的更大的可表示int。
请参阅http://php.net/manual/en/reserved.constants.php

非常好的观点,先生!是的,这确实以多种方式解决了问题,所以我会接受这个答案。谢谢! - Mike S

4
你的数字中多了一个额外的5。这样写:
92233720368547755807

应该是这样的:
9223372036854775807

额嘿嘿。哎呀,没意识到。谢谢指出! - Mike S

-1
你的问题是,超过 INT_MAX 的每个数字都会被转换为浮点数,从而失去精度。如果将其与字符串进行比较,则始终返回 false。
请使用 bcmath 函数来处理这样的大数字。

2
当它应该是整数时,INT_MAX就可以了。当它应该是浮点数时,已经计划使用bcmath来保持所需的精度。顺便说一下,这也可以作为注释留下来。 - Mike S
1
哦?真的吗?一个问题没有涉及浮点数,只与整数保持一致(因此也会测试它们的溢出),这个问题不清楚吗? - Mike S
我该如何使这个测试返回正结果?移除一切并返回true; - Rok Kralj
是的,但在这种情况下,它只是一个支持我的论点的例子,说明问题不清楚。 - Rok Kralj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接