现在的位置: 首页PHP技术 > 正文
PHP 处理int64的一些问题和解决方法
关键词:无 ┊ 来源: 原创收藏

PHP内部只有signed int 32,在处理unsigned int 32的时候,通常直接转float就可以正常操作。而处理int64时会受到操作系统字长限制,比如:

1
2
3
4
5
//32bit php:
echo PHP_INT_MAX; // 2^31 - 1
 
//64bit php:
echo PHP_INT_MAX; // 2^63 - 1

由于这个限制,处理比2^31更大的数字的时候必定会发生溢出导致得到一个负数(符号位被设置为1)。通常解决方法是,转成float。这在大多数情况下可以解决问题。但,最近碰到一个问题,某一个数据是使用 unsigned int 64 存储的,读取以后在php里被表示为了科学技术法:

1
2
3
4
5
6
7
8
9
$a = 12345678901234567890;
 
echo $a;
 
//1.2345678901235E+19
 
echo $a + 1;
 
//1.2345678901235E+19

而且,被隐掉的数字完全无法参与后续运算!

后来在64bit的php下同样如此,唯一好的一点是,64bit的php本身的PHP_INT_MAX 比较大,可以满足9223372036854775807 以下的int数据处理。但可笑的是:

1
echo floatval(PHP_INT_MAX); //  9.2233720368548E+18

……居然又发生了截断……

恩,处理办法是: php.ini里有一个precision的设置,默认是14,影响float的精度设置。由于正常的unsigned int64的位数是20位,所以,把这个数字设置到20以上,就可以保证int64的正常处理。这个处理同样会应影响json_decode和其他一些函数:

1
2
3
4
5
6
ini_set('precision', 20);
 
var_export(json_decode('{"a":1234567890123456789}'));
//stdClass::__set_state(array(
//'a' => 1234567890123456789,
//))

但很奇怪的是:

1
2
3
4
var_export(json_decode('{"a":12345678901234567890}'));
//stdClass::__set_state(array(
//'a' => 12345678901234567168,
//))

可以看到a的值已经发生变化,估计是signed int64也开始发生溢出,暂时未找到连这个也能搞定的完美解决办法……
如果不需要int64参与数学运算,想办法转成string吧……

相关文章
    暂无相关文章
本文由 jack 发布于 1932天 3小时 36分钟前,目前已有 8576 人浏览
欢迎大家转载分享,请注明来源及链接;商业媒体转载请获得授权,谢谢合作!
 

添加评论