2016-03-02 82 views
8

对不起,我不知道怎么称呼这个。为什么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(10e15); // float 

输出:

警告:兰特()预计参数2为整数,浮点数给出/srv/webroot-sandbox/index.php(73 ):EVAL()倒是线代码1

警告:兰特()预计参数2为整数,浮点数给出/srv/webroot-sandbox/index.php(73 ):EVAL()'d代码第2行

警告:rand()需要参数2将整数,浮点数给出 在/srv/webroot-sandbox/index.php(73):的eval()'d码3

578009006101638016 
69608699344098568 
7596902768127620 

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

线有人能解释这是怎么回事?这是PHP 7,它在PHP 5中运行正常(至少,我没有得到任何警告)。

+2

仍然在搜索,但可能是它超过​​了整数的大小... – FirstOne

+0

嗯也许它试图施展和失败在一定的规模?但有趣的是,根据手册,它在PHP 5 – MightyPork

+0

中运行正常:http://php.net/manual/en/language.types.integer.php一旦超出限制,就会出错。这是特定于php7。 – durbnpoisn

回答

11

PHP整数是有符号的64位值(除非你是在32位安装),所以他们去(大约)

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

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

所以你的“坏”值只是太大而不能存储为整数的整数,并且PHP正在转换为浮动以试图尽可能保留尽可能多的值。

而且由于你有10e18,那实际上是1e19,并且在max_int范围之外。

+0

将有趣的是,也将这与PHP 5的行为进行比较,遗憾的是我已经升级了... – MightyPork

+1

@MightyPork,行为与任何系统,32位整数max是2^32/2-1,64位整数max是2^64/2-1。 (无符号将是2^32-1,2^64-1但PHP不允许无符号整数如果IIRC) – Devon

+1

我的5.5.9匹配上面。但请注意,在Windows中,无论底层平台是什么,php5都将所有整数视为32位。例如phpwin 64bit仍然使用32位整数。 –

6

你的问题可以是依赖于平台的作为一个整数范围:

  • 32位平台是-2,147,483,6482,147,483,647
  • 64位平台-9,223,372,036,854,775,8089,223,372,036,854,775,808

对我来说,运行一个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 

该输出与您的结果直接相关,可能会解释小提琴或您的虚拟主机以显示不同的结果。

它表现不同上PHP 7的理由进行说明here

以前,内部功能将静默截断从float到整数的强制产生数字 当浮子太大 表示作为整数。现在,E_WARNING将被发射,并返回NULL 。

相关问题