dsideal2015
2016-03-02 19:11 阅读 6
已采纳

为什么php认为大的int是浮点数(但有时只是)?

Sorry for the bad title, but I dunno how to call this.

echo rand(0,10e20) . "
"; // bad
echo rand(0,10e19) . "
"; // bad
echo rand(0,10e18) . "
"; // bad
echo rand(0,10e17) . "
"; // OK
echo rand(0,10e16) . "
";
echo rand(0,10e15) . "

";

var_dump(10e20); // float
var_dump(10e15); // float

Output:

Warning: rand() expects parameter 2 to be integer, float given in /srv/webroot-sandbox/index.php(73) : eval()'d code on line 1

Warning: rand() expects parameter 2 to be integer, float given in /srv/webroot-sandbox/index.php(73) : eval()'d code on line 2

Warning: rand() expects parameter 2 to be integer, float given in /srv/webroot-sandbox/index.php(73) : eval()'d code on line 3

578009006101638016
69608699344098568
7596902768127620

float(1.0E+21)
float(1.0E+16)

Can someone explain what's going on? This is PHP 7, it worked fine in PHP 5 (well, at least I didn't get any warnings).

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

2条回答 默认 最新

  • 已采纳
    duan_2000 duan_2000 2016-03-02 19:31

    PHP ints are signed 64bit values (unless you're on a 32bit install), so they go (roughly)

    -9,223,372,036,854,775,808 -> +9,223,372,036,854,775,808
    

    In scientific notation, -9.2e18 -> +9.2e18

    So your "bad" values are simply integers that are too large to store as integers, and PHP is converting to float to try and preserve as much of the value as is possible.

    And since you have 10e18, that's actually 1e19, and outside the max_int range.

    点赞 评论 复制链接分享
  • duanhua9398 duanhua9398 2016-03-02 19:30

    Your question can be platform dependent as the integer range of a:

    • 32 bit platform is -2,147,483,648 to 2,147,483,647
    • 64 bit platform is -9,223,372,036,854,775,808 to 9,223,372,036,854,775,808

    For me, running a 64 bit system it gives the following result.

    var_dump(10e20 > PHP_INT_MAX); // true
    var_dump(10e19 > PHP_INT_MAX); // true
    var_dump(10e18 > PHP_INT_MAX); // true
    var_dump(10e17 > PHP_INT_MAX); // false
    var_dump(10e16 > PHP_INT_MAX); // false
    var_dump(10e15 > PHP_INT_MAX); // false
    

    This output directly correlates with your results and might explain a fiddle or your webhost to show different results.

    The reason it behave differently on PHP 7 is explained here:

    Previously, internal functions would silently truncate numbers produced from float-to-integer coercions when the float was too large to represent as an integer. Now, an E_WARNING will be emitted and NULL will be returned.

    点赞 评论 复制链接分享

相关推荐