当前位置: 首页 > 后端技术 > PHP

【PHP源码阅读】number_format函数

时间:2023-03-30 01:55:37 PHP

上次讲了PHP如何解析大整数。一下就把number_format的处理搞定了,接下来详细阅读这个函数的源码。下面是一个小分析。函数原型stringnumber_format(float$number[,int$decimals=0])stringnumber_format(float$number,int$decimals=0,string$dec_point=".",string$thousands_sep=",")函数可以接受1,2,4个参数(详见代码实现)。如果只提供第一个参数,则去掉数字的小数部分,每个千位分隔符为小写逗号“,”;如果提供了两个参数,则该数字将保留小数点后的位数,您可以设置该值同上;如果提供四个参数,number将保留小数部分长度,小数点替换为dec_point,千位分隔符替换为thousands_sepPHP_FUNCTION(number_format)//number//你要格式化的数字//num_decimal_places//保留的小数位数//dec_separator//指定小数点显示的字符//thousands_separator//指定千位分隔符显示的字符/*{{{protostringnumber_format(floatnumber[,intnum_decimal_places[,stringdec_separator,stringthousands_separator]])Formatsanumberwithgroupedthousands*/PHP_FUNCTION(number_format){//期望number_format的第一个参数num是double类型,字面常量已经在词法阶段转换双数;zend_longdec=0;char*thousand_sep=NULL,*dec_point=NULL;charthousand_sep_chr=',',dec_point_chr='.';size_tthousand_sep_len=0,dec_point_len=0;//解析参数ZEND_PARSE_PARAMETERS_START(1,4)Z_PARAM_DOUBLE(num)//获取double类型numZ_PARAM_OPTIONALZ_PARAM_LONG(dec)Z_PARAM_STRING_EX(dec_point,dec_point_len,1,0)Z_PARAM_STRING_EX(thousand_sep,thousand_sep_len,1,0)ZEND_PARSE_PARAMETERS_END();switch(ZEND_NUM_ARGS()){案例1:RETURN_STR(_php_math_number_format(num,0,dec_point_chr,thousand_sep_chr));休息;情况2:RETURN_STR(_php_math_number_format(num,(int)dec,dec_point_chr,thousand_sep_chr));休息;案例4:if(dec_point==NULL){dec_point=&dec_point_chr;dec_point_len=1;}if(thousand_sep==NULL){thousand_sep=&thousand_sep_chr;thousand_sep_len=1;}//_php_math_number_format_ex//真正的处理函数,在这个文件的1107行休息;默认值:WRONG_PARAM_COUNT;}}/*}}}*/代码执行流程图_php_math_number_format_ex函数实现各种参数的个数,最终会调用_php_math_number_format_ex函数该函数的主要功能是:处理负数;根据要保留的小数点对浮点数进行舍入;调用strpprintf函数将浮点表达式转换为字符串表示形式;计算需要分配给结果变量的字符串的长度;将结果复制到return值中(如果有千字符,则用千字符分隔)strpprintf是实现浮点数和字符串转换的函数。上面说到转换最终是调用php_conv_fp函数完成的(这里是通过gdb调试定位完成的),php_conv_fp函数,追查到,调用了zend_dtoa函数。更详细的注意事项见github项目提交记录。小结看了这个函数的源码,了解到的是浮点数和字符串相互转换的实现细节。字符串和浮点数的关系比较复杂,后面会继续学习。原创文章,文笔有限,见识浅薄,如有不妥之处,敬请指出。更多精彩内容,请关注我公众号。