首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

從零手寫字符串轉浮點數:StrToFloat 完整實現(支持正負號、小數、異常截斷)

     編輯:關於C

背景:經典面試題的工程級落地

面試高頻題:「不調用庫函數,實現 float StrToFloat(const char* str)」。看似簡單,實則坑多:符號位、小數點、非法字符截斷、溢出、邊界條件……作者在空閒時間完成雙版本(ANSI/Unicode)實現,並附帶豐富測試用例,堪稱教科書級參考。

設計思路:單次掃描、雙累加器

  • 單遍歷:一個 while(*pSor) 循環搞定所有字符。
  • 狀態機:bNegative 標記符號,bDec 標記是否進入小數部分。
  • 雙累加器:
    • 整數部:fInteger = fInteger * 10 + digit
    • 小數部:fDecimal += digit * fDecPower; fDecPower *= 0.1f(避免 pow 開銷)
  • 異常即停:遇非法字符(含第二個小數點)立即返回已解析值,符合 atof 風格。

核心代碼(ANSI 版)

float StrToFloatA(const char* pstrfloat) {
    if (!pstrfloat) return 0.0f;

    bool bNegative = false, bDec = false;
    const char* p = pstrfloat;
    float fInt = 0.0f, fDec = 0.0f, fDecPower = 0.1f;

    // 符號
    if (*p == '-') { bNegative = true; p++; }
    else if (*p == '+') { p++; }

    while (*p != '\0') {
        char ch = *p;
        if (bDec) {                     // 小數部分
            if (ch >= '0' && ch <= '9') {
                fDec += (ch - '0') * fDecPower;
                fDecPower *= 0.1f;
            } else break;               // 非法字符截斷
        } else {                        // 整數部分
            if (ch >= '0' && ch <= '9') {
                fInt = fInt * 10.0f + (ch - '0');
            } else if (ch == '.') {
                bDec = true;
            } else break;
        }
        p++;
    }
    float result = fInt + fDec;
    return bNegative ? -result : result;
}

Unicode 版 StrToFloatW 邏輯完全一致,僅將 char 換為 wchar_t、字面量加 L 前綴,並通過宏 StrToFloat 根據 UNICODE 自動切換。

測試用例覆蓋場景

輸入預期行為
L"12.34"正常轉換 12.34
L"a23"首字符非法,返回 0
L"1234"純整數
L"12.34.56"第二個點截斷,返回 12.34
L".34"無整數部,返回 0.34
L"-56.34"負數
L"-."僅符號+點,返回 -0
L"-0"負零

已知局限與改進方向

  • 不支持科學計數法(1.23e-4),需擴展狀態機處理 e/E。
  • float 精度有限,長小數會丟失精度;生產環境建議用 double 或 long double 累加,最後再縮窄。
  • 溢出未檢測,極大數值會變 inf,可引入 FLT_MAX 邊界判斷。
  • 空白字符未跳過,標準庫 strtod 會跳過前導空白。

總結

這份實現展示了「單遍歷 + 狀態機 + 雙累加」的經典模式,代碼清晰、邊界處理完善,極適合面試白板寫代碼或嵌入式無庫環境移植。讀者可在其基礎上按需擴展科學計數法、錯誤碼返回等特性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved