15

PHP_INT_MIN 和 -9223372036854775808

 4 years ago
source link: https://www.laruence.com/2020/02/28/5261.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

刚刚吃饭的时候想说今天再写点啥? 突然想起来前几天有人在微博上评论我的一个PHP的面试题:

ZJN773B.jpg!web

首先,我要申明这样的面试题,其实很没意思。 不过作为一个有趣的知识点,我今天就说说这个小问题吧。

我们知道64位的整数的表值范围是-9223372036854775808 到 9223372036854775807.

在64位系统上PHP内部是使用有符号的64位整形来表示IS_LONG, 分别有俩个常量来表示这俩个值, 分别是PHP_INT_MIN和PHP_INT_MAX.

在64位平台上,PHP_INT_MIN就等于-9223372036854775808,那题目的意思是啥呢? 我们输出下看看:

var_dump(PHP_INT_MAX);
var_dump(-9223372036854775808);

输出:

int(9223372036854775807)
float(-9.2233720368548E+18)

那是什么造成了这个问题呢?

在PHP编译器处理输入文件输入的时候,对于负数字面量它的处理方式是:

-{LNUM}
   => '-' expr { $$ = zend_ast_create(ZEND_AST_UNARY_MINUS, $2); }
   => UNARY_MINUS: 0 - expr

也就是,首先把负号后面的数字作为一个整形接受进来,然后在把它求负。

于是这就造成了这个问题, 开头我们说了64位的最大正表值是9223372036854775807,那当PHP处理-9223372036854775808的时候, 9223372036854775808超出了64位整形的最大正表值范围,PHP没有办法用一个有符号64位整形存储它,于是只能把它自动转成了DOUBLE类型。 于是接下来....

那PHP_INT_MAX又是怎么回事呢? 其实PHP_INT_MIN的定义不是一个常数,而是一个表达式,类似:

#define PHP_INT_MIN  -9223372036854775807 - 1

于是就不会触发这个限制,就能正常表达PHP_INT_MIN啦。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK