可以看到,zend引擎在对PHP代码在对纯数字的表达式做词法分析的时刻,先断定数字是否有可能会溢出,如不雅有可能溢出,先测验测验将其用LONG类型保存,如不雅溢出,先用zend_strtod将其转换为double类型,然后用double类型的zval构造体保存之。
经由过程gdb调试,追查到number_format函数,在PHP底层最终会调用php_conv_fp函数对数字进行转换:
函数原型如下:
- PHPAPI char * php_conv_fp(register char format, register double num, boolean_e add_dp, int precision, char dec_point, bool_int * is_negative, char *buf, size_t *len);
这里接收的参数num是一个double类型,是以,如不雅传入的是字符串类型数字的话,number_format函数也会将其转成double类型传入到php_conf_fp函数里。而这个double类型的num最终之所以输出为17978812896666957824,是因为进行科学计数法之后的精度损掉了,从新转成double时就恢复不了本来的值。在C说话下验证:
- double local_dval = 1.7978812896666958E+19;
- printf("%f\n", local_dval);
输出的结不雅就是
17978812896666957824.000000
所以,这不是PHP的bug,它就是如许的。
词攀类问题解决筹划
对于存储,跨越PHP最大年夜表示范围的纯整数,在MySQL中可以应用bigint/varchar保存,MySQL在萌芽出来的时刻会将其应用string类型保存的。
number_format掉败的原因
对于赋值,在PHP里,如不雅遇涤眯大年夜整数须要赋值的话,不要测验测验用整型类型去赋值,比如,不要用以下这种:
根据之前底时掘印出来的内容,在2-6的时刻就看到了一个handler的值:
- $var = 17978812896666957068;
推荐阅读
51CTO诚邀您9月23号和秒拍/国美/美团云专家一路聊智能CDN的优化之路,抓紧时光哦! BIOS,英文"Basic Input Output System"的缩略词,直译过来后中文名称就是"根本输入输出体系",这些专业>>>详细阅读
本文标题:自上而下,逐步揭开PHP解析大整数的面纱
地址:http://www.17bianji.com/lsqh/37473.html
1/2 1