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

为什么php认为大整数是浮点数(但只是有时)?,php,Php,很抱歉标题不好,但我不知道怎么称呼这个 echo rand(0,10e20) . "\n"; // bad echo rand(0,10e19) . "\n"; // bad echo rand(0,10e18) . "\n"; // bad echo rand(0,10e17) . "\n"; // OK echo rand(0,10e16) . "\n"; echo rand(0,10e15) . "\n\n"; var_dump(10e20); // float var_dump(10e

很抱歉标题不好,但我不知道怎么称呼这个

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

var_dump(10e20); // float
var_dump(10e15); // float
输出:

警告:rand()要求参数2为整数,给定浮点 在/srv/webroot sandbox/index.php(73)中,第1行的代码是eval()

警告:rand()要求参数2为整数,给定浮点 在/srv/webroot sandbox/index.php(73)中,第2行的代码是eval()

警告:rand()要求参数2为整数,给定浮点 在/srv/webroot sandbox/index.php(73)中,第3行的代码是eval()


有人能解释一下发生了什么事吗?这是PHP7,它在PHP5中运行良好(至少我没有收到任何警告)。

您的问题可能与平台有关,因为a的整数范围为:

  • 32位平台是
    -2147483648
    2147483647
  • 64位平台是
    -9223372036854775808
    9223372036854775808
对我来说,运行64位系统会得到以下结果

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
此输出与您的结果直接相关,并可能解释fiddle或您的Web主机显示不同结果的原因

解释了它在PHP 7上表现不同的原因:

以前,内部函数会自动截断数字 当浮点太大时,从浮点强制到整数强制生成 表示为整数。现在,将发出E_警告并为空 将被退回


PHP int是有符号的64位值(除非您安装的是32位),所以它们(大致上)是

在科学记数法中,-9.2e18->+9.2e18

因此,您的“坏”值只是太大而无法存储为整数的整数,PHP正在转换为float以尽可能多地保留值


既然你有
10e18
,那实际上是
1e19
,并且超出了最大int范围。

仍在搜索,但可能是它超过了int的大小……嗯,可能它试图强制转换,但在一定程度上失败了?但有趣的是,根据手册,它在PHP5中工作正常:一旦超出限制,就会出错。这是php7.hm特有的。yea自己在谷歌上找到的。仍然值得一提的是,我不会是唯一一个偶然发现这一点的人。
var_dump
不在乎您是否提供float或int,但
rand
会。您是否尝试在php7中进行设置?将其与PHP5的行为进行比较会很有趣,很遗憾,我已经升级了…@MightyPork,该行为与任何系统相同,32位整数最大值为2^32/2-1,64位整数最大值为2^64/2-1。(Unsigned应该是2^32-1,2^64-1,但是如果IIRC的话,PHP不允许使用Unsigned整数)我的5.5.9与上面的匹配。但请注意,在Windows中,无论底层平台是什么,php5都将所有INT视为32位。e、 phpwin 64位仍然使用32位整数。我之所以想尝试php5,是因为rand()警告以前没有出现过。有点奇怪,当时它是如何将这个大数字与int匹配的。它也会做同样的事情,因为rand()需要int。它以前可能只是一个无声的错误,PHP7将其升级为完整的警告。我在5.5.9中没有收到任何警告,因为int的大小过大。
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
-9,223,372,036,854,775,808 -> +9,223,372,036,854,775,808