成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

[PHP源碼閱讀]number_format函數(shù)

itvincent / 2677人閱讀

摘要:上次講到是如何解析大整數(shù)的,一筆帶過了的處理,再詳細(xì)閱讀該函數(shù)的源碼,以下是小分析??偨Y(jié)閱讀完這個函數(shù)的源碼,學(xué)習(xí)到的是浮動數(shù)與字符串的互相轉(zhuǎn)換的實現(xiàn)細(xì)節(jié),字符串與浮點數(shù)之間的關(guān)系較復(fù)雜,之后還要繼續(xù)學(xué)習(xí)。

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

函數(shù)原型
string number_format ( float $number [, int $decimals = 0 ] )

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

函數(shù)可以接受1、2、4個參數(shù)(具體可以看代碼的實現(xiàn))。

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

PHP_FUNCTION(number_format)
// number
// 你要格式化的數(shù)字
// num_decimal_places
// 要保留的小數(shù)位數(shù)
// dec_separator
// 指定小數(shù)點顯示的字符
// 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的第一個參數(shù)num是double類型的,在詞法階段已經(jīng)對字面量常量做了轉(zhuǎn)換
    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;
    // 解析參數(shù)
    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
        // 真正處理的函數(shù),在本文件第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;
    }
}
/* }}} */
代碼執(zhí)行流程圖

_php_math_number_format_ex

函數(shù)實現(xiàn)的各種參數(shù)數(shù)量,最終都會調(diào)用_php_math_number_format_ex函數(shù)。函數(shù)主要做的是:

處理負(fù)數(shù);
根據(jù)要保留的小數(shù)點對浮點數(shù)進(jìn)行四舍五入;
調(diào)用strpprintf函數(shù)將浮點數(shù)表達(dá)式轉(zhuǎn)成字符串表示;
計算需要分配給結(jié)果變量的字符串長度;
將結(jié)果拷貝到返回值中(如果有千位符,則進(jìn)行千位符分割)

strpprintf

這個函數(shù)是實現(xiàn)浮點數(shù)與字符串的轉(zhuǎn)換,如上文所說,最終是調(diào)用了php_conv_fp函數(shù)做的轉(zhuǎn)換(這里是通過gdb調(diào)試做的定位),而php_conv_fp函數(shù),往下追蹤,調(diào)用的是zend_dtoa函數(shù),

更多細(xì)節(jié)注解,見github項目提交記錄。

總結(jié)

閱讀完這個函數(shù)的源碼,學(xué)習(xí)到的是浮動數(shù)與字符串的互相轉(zhuǎn)換的實現(xiàn)細(xì)節(jié),字符串與浮點數(shù)之間的關(guān)系較復(fù)雜,之后還要繼續(xù)學(xué)習(xí)。

原創(chuàng)文章,文筆有限,才疏學(xué)淺,文中若有不正之處,萬望告知。

更多精彩內(nèi)容,請關(guān)注個人公眾號。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/25882.html

相關(guān)文章

  • 自上而下,逐步揭開PHP解析大整數(shù)的面紗

    摘要:而這個類型的最終之所以輸出為,是因為進(jìn)行科學(xué)計數(shù)法之后的精度丟失了,重新轉(zhuǎn)成時就恢復(fù)不了原來的值。此類問題解決方案對于存儲,超過最大表示范圍的純整數(shù),在中可以使用保存,在查詢出來的時候會將其使用類型保存的。 遇到的問題 最近遇到一個PHP大整數(shù)的問題,問題代碼是這樣的 $shopId = 17978812896666957068; var_dump($shopId); 上面的代碼輸出...

    qingshanli1988 評論0 收藏0
  • 系統(tǒng)的講解 - PHP 浮點數(shù)高精度運算

    摘要:浮點數(shù)類型包括單精度浮點數(shù)和雙精度浮點數(shù)。小結(jié)通過浮點數(shù)精度的問題,了解到浮點數(shù)的小數(shù)用二進(jìn)制的表示。以后,在使用浮點數(shù)運算的時候,一定要慎之又慎,細(xì)節(jié)決定成敗。 概述 記錄下,工作中遇到的坑 ... 關(guān)于 PHP 浮點數(shù)運算,特別是金融行業(yè)、電子商務(wù)訂單管理、數(shù)據(jù)報表等相關(guān)業(yè)務(wù),利用浮點數(shù)進(jìn)行加減乘除時,稍不留神運算結(jié)果就會出現(xiàn)偏差,輕則損失幾十萬,重則會有信譽損失,甚至吃上官司,我...

    makeFoxPlay 評論0 收藏0
  • php記錄

    摘要:獲取執(zhí)行的語句天前月前周前二進(jìn)制安全簡單說就是傳入的參數(shù)支持二進(jìn)制數(shù)據(jù),包括這種在中表示字符串結(jié)束的字符返回由于是非二進(jìn)制安全,誤判為相等返回負(fù)數(shù)捕捉異常中斷腳本執(zhí)行是否完成異 獲取php pdo 執(zhí)行的sql語句 class MyPDOStatement extends PDOStatement { protected $_debugValues = null; prote...

    tainzhi 評論0 收藏0
  • PHP算法:一個數(shù)字平分為N份,并且總值相等

    摘要:有的時候,你可能有這種需求,需要將一個數(shù)字分為等份,多余的自動分配給其中一個數(shù)字。 有的時候,你可能有這種需求,需要將一個數(shù)字分為N等份,多余的自動分配給其中一個數(shù)字。 實現(xiàn)方法有如下兩種,當(dāng)然還有其他的,比如截取substr等,有興趣的可以自己嘗試: 第一種方法,采用bc函數(shù),即PHP的數(shù)學(xué)擴展庫bcmath,具體可以點擊如下鏈接查看更多了解 BC數(shù)學(xué)函數(shù) http://ph...

    Eric 評論0 收藏0
  • PHP 處理金額

    摘要:導(dǎo)語涉及到金額的代碼,一定要謹(jǐn)慎處理。所幸的是,金額一般不會有太多的小數(shù)。那么存儲的時候呢,一言以蔽之,以分為單位進(jìn)行存儲。格式化金額下面是格式化金額的實例格式化金額參考資料關(guān)于浮點數(shù)你應(yīng)該知道的浮點數(shù)的一個常見問題的解答。 導(dǎo)語 涉及到金額的代碼,一定要謹(jǐn)慎處理。剛好最近做了相關(guān)的功能,下面大概說一下。 存儲 PHP 的浮點數(shù)是不能精確計算的,具體的可以看這篇文章。所幸的是,金額一般...

    asce1885 評論0 收藏0

發(fā)表評論

0條評論

itvincent

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<