测试 PHP 中的整数溢出

发布于 2024-12-03 07:52:21 字数 1236 浏览 0 评论 0原文

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

$_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 );

我得到这个:

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;
    }
}

问题是这样的:< strong>我怎样才能让这个测试返回阳性?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

星星的軌跡 2024-12-10 07:52:21

使用 PHP_INT_MAX 常量:

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

这将解决您的问题,并使您的测试更加可移植(例如,它也可以在 32 位系统上运行)。

PHP_INT_MAX 的值是您的 PHP 版本可表示的较大 int 值。

请参阅http://php.net/manual/en/reserved.constants.php

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

偏爱你一生 2024-12-10 07:52:21

您的号码中多了一个 5。这个:

92233720368547755807

应该是这个:

9223372036854775807

You have an extra 5 in your number. This:

92233720368547755807

Should be this:

9223372036854775807
风轻花落早 2024-12-10 07:52:21

您的问题是,高于 INT_MAX 的数字会转换为浮点型,这会损失精度。如果将它与 String 进行比较,它总是返回 false。

请使用 bcmath 函数来处理如此大的数字。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文