首頁  >  文章  >  後端開發  >  php閱讀number_format函數的原始碼分享

php閱讀number_format函數的原始碼分享

黄舟
黄舟原創
2017-09-22 09:11:552117瀏覽

上次講到PHP是如何解析大整數的,一筆帶過了number_format的處理,再詳細閱讀該函數的源碼,以下是小分析。

函數原型

string number_format ( float $number [, int $decimals = 0 ] )

string number_format ( float $number , int $decimals = 0 , string $dec_point = "." , string $thousands_sep = "," )

函數可以接受1、2、4個參數(具體可以看​​程式碼的實作)。

如果只提供第一個參數,number的小數部分會被去掉,並且每個千位分隔符號都是英文小寫逗號"," ;
如果提供兩個參數,number將保留小數點後的位數到你設定的值,其餘同樓上;
如果提供了四個參數,number 將保留decimals個長度的小數部分, 小數點被替換為dec_point,千位分隔符替換為thousands_sep

PHP_FUNCTION(number_format)

// number
// 你要格式化的数字
// num_decimal_places
// 要保留的小数位数
// dec_separator
// 指定小数点显示的字符
// thousands_separator
// 指定千位分隔符显示的字符
/* {{{ proto string number_format(float number [, int num_decimal_places [, string dec_separator, string thousands_separator]])
   Formats a number with grouped thousands */
PHP_FUNCTION(number_format)
{
    // 期望number_format的第一个参数num是double类型的,在词法阶段已经对字面量常量做了转换
    double num;
    zend_long dec = 0;
    char *thousand_sep = NULL, *dec_point = NULL;
    char thousand_sep_chr = ',', dec_point_chr = '.';
    size_t thousand_sep_len = 0, dec_point_len = 0;
    // 解析参数
    ZEND_PARSE_PARAMETERS_START(1, 4)
        Z_PARAM_DOUBLE(num)// 拿到double类型的num
        Z_PARAM_OPTIONAL
        Z_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()) {
    case 1:
        RETURN_STR(_php_math_number_format(num, 0, dec_point_chr, thousand_sep_chr));
        break;
    case 2:
        RETURN_STR(_php_math_number_format(num, (int)dec, dec_point_chr, thousand_sep_chr));
        break;
    case 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行
        RETVAL_STR(_php_math_number_format_ex(num, (int)dec,
                dec_point, dec_point_len, thousand_sep, thousand_sep_len));
        break;
    default:
        WRONG_PARAM_COUNT;
    }
}
/* }}} */

程式碼執行流程圖

php閱讀number_format函數的原始碼分享

_php_math_number_format_ex

#_php_math_number_format_ex




##php_math_number_format_ex

##php_math_number_format_ex

##php_math_number_format_ex

##php_math_number_format_ex##############php_math_number_format_ex##############」函數實現的各種參數數量,最終都會呼叫_php_math_number_format_ex函數。函數主要做的是:######處理負數;###根據要保留的小數點對浮點數進行四捨五入;###呼叫strpprintf函數將浮點數表達式轉成字串表示;###計算需要指派給結果變數的字串長度;###將結果拷貝到傳回值(如果有千位符,則進行千位符分割)######strpprintf######這個函數是實現浮點數與字串的轉換,如上文所說,最終是調用了php_conv_fp函數所做的轉換(這裡是透過gdb調試做的定位),而php_conv_fp函數,往下追踪,調用的是zend_dtoa函數,## ####更多細節註解,請參閱github專案提交記錄。 ######總結######閱讀完這個函數的源碼,學習到的是浮動數與字串的互相轉換的實作細節,字串與浮點數之間的關係較複雜,之後還要繼續學習。 ###

以上是php閱讀number_format函數的原始碼分享的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn