其實幾年前實作過一個面試題版本的,參考:浮點數字元串轉換成浮點數實作。
最近因為某些原因又拿了出來,做了一些簡單的修改,支援了前端空格處理,溢出檢測等等,當然精度處理這個難度有點大,沒有特殊處理。另外帶E(e)的浮點數字元串也進行了處理。需要特别說明的時候,運作時庫裡面是有一個類似的轉換函數的,寫一寫隻是練練手而已。
頭檔案
/* -------------------------------------------------------------------------
// 檔案名 : KString2Float.h
// 建立者 : magic
// 建立時間 : 2015/7/28 17:36:43
// 功能描述 :
//
// $Id: $
// -----------------------------------------------------------------------*/
#ifndef __KSTRING2FLOAT_H__
#define __KSTRING2FLOAT_H__
#include <float.h>
#include <windows.h>
// -------------------------------------------------------------------------
namespace NSUtil
{
// -------------------------------------------------------------------------
// 函數 : atofloat
// 功能 : 将一個字元串轉換為浮點數
// 傳回值 : float
// 參數 : const char* s
// 附注 :
// -------------------------------------------------------------------------
float atofloat(const char* s);
// -------------------------------------------------------------------------
// 函數 : wtofloat
// 功能 : 将一個寬字元串轉換為浮點數
// 傳回值 : float
// 參數 : const wchar_t* s
// 附注 :
// -------------------------------------------------------------------------
float wtofloat(const wchar_t* s);
// -------------------------------------------------------------------------
// 函數 : strtofloatT
// 功能 : 将一個字元串轉換為浮點數
// 傳回值 : float
// 參數 : const tchar* s
// 附注 :
// -------------------------------------------------------------------------
template<typename tchar>
float strtofloatT(const tchar* s)
{
// check
if (!s)
return 0.0f;
float fResult = 0.0f; // 存儲結果
tchar c = 0;
// 整數部分
bool bNegative = false;
float fInteger = 0.0f;
// 小數部分
bool bDec = false;
float fDecimal = 0.0f;
float fDecPower = 0.1f;
// 指數部分
bool bMeetE = false;
bool bEInFirst = true; // e不能在最前面
bool bNegativeExponent = false;
unsigned int nIntegerExponent = 0;
float fExponentData = 1.0f;
c = *s++;
/* skip whitespace */
while (0x20 == c)
c = *s++;
// 進行首位判斷,判斷是否是負數
if (0x2d == c)
{
bNegative = true;
c = *s++;
}
else if (0x2b == c)
{
bNegative = false;
c = *s++;
}
while (0 != c)
{
if (bMeetE)
{
// 指數部分
if (c >= 0x30 && c <= 0x39)
{
nIntegerExponent = nIntegerExponent * 10 + c - 0x30;
}
else
{
break;
}
}
else
{
if (0x65 == c || 0x45 == c)
{
if (bEInFirst)
break;
// 确定指數的符号
c = *s;
if (0 == c)
break;
if (0x2d == c)
{
bNegativeExponent = true;
c = *s++;
}
else if (0x2b == c)
{
bNegativeExponent = false;
c = *s++;
}
bMeetE = true;
}
else if (bDec)
{
bEInFirst = false;
// 小數部分
if (c >= 0x30 && c <= 0x39)
{
fDecimal += (c - 0x30) * fDecPower;
fDecPower = fDecPower * 0.1f;
}
else
{
break;
}
}
else
{
bEInFirst = false;
// 整數部分
if (c >= 0x30 && c <= 0x39)
{
fInteger = fInteger * 10.0f + c - 0x30;
}
else if (c == 0x2e)
{
bDec = true;
}
else
{
break;
}
}
}
c = *s++;
}
// 指數處理
if (bMeetE)
{
float fExponent = bNegativeExponent ? 0.1f : 10.0f;
while (nIntegerExponent > 0)
{
fExponentData *= fExponent;
--nIntegerExponent;
}
}
// 溢出檢測
fResult = (bNegative? -(fInteger + fDecimal) : fInteger + fDecimal);
fResult *= fExponentData;
if (fResult > FLT_MAX)
{
fResult = FLT_MAX;
}
else if (fResult < -FLT_MAX)
{
fResult = -FLT_MAX;
}
else if (fResult > 0 && fResult < FLT_MIN)
{
fResult = FLT_MIN;
}
else if (fResult < 0 && fResult > -FLT_MIN)
{
fResult = -FLT_MIN;
}
return fResult;
}
#if defined(UNICODE) || defined(_UNICODE)
#define strtofloat wtofloat
#else
#define strtofloat atofloat
#endif // !UNICODE
} // end NSUtil
// -------------------------------------------------------------------------
// $Log: $
#endif /* __KSTRING2FLOAT_H__ */
實作代碼
/* -------------------------------------------------------------------------
// 檔案名 : KString2Float.cpp
// 建立者 : magic
// 建立時間 : 2015/7/28 17:36:48
// 功能描述 :
//
// $Id: $
// -----------------------------------------------------------------------*/
#include "stdafx.h"
#include "KString2Float.h"
// -------------------------------------------------------------------------
namespace NSUtil
{
// -------------------------------------------------------------------------
// 函數 : atofloat
// 功能 : 将一個字元串轉換為浮點數
// 傳回值 : float
// 參數 : const char* s
// 附注 :
// -------------------------------------------------------------------------
float atofloat(const char* s)
{
// check
if (!s)
return 0.0f;
float fResult = 0.0f; // 存儲結果
char c = 0;
// 整數部分
bool bNegative = false;
float fInteger = 0.0f;
// 小數部分
bool bDec = false;
float fDecimal = 0.0f;
float fDecPower = 0.1f;
// 指數部分
bool bMeetE = false;
bool bEInFirst = true; // e不能在最前面
bool bNegativeExponent = false;
unsigned int nIntegerExponent = 0;
float fExponentData = 1.0f;
c = *s++;
/* skip whitespace */
while (' ' == c)
c = *s++;
// 進行首位判斷,判斷是否是負數
if ('-' == c)
{
bNegative = true;
c = *s++;
}
else if ('+' == c)
{
bNegative = false;
c = *s++;
}
while ('\0' != c)
{
if (bMeetE)
{
// 指數部分
if (c >= '0' && c <= '9')
{
nIntegerExponent = nIntegerExponent * 10 + c - '0';
}
else
{
break;
}
}
else
{
if ('e' == c || 'E' == c)
{
if (bEInFirst)
break;
// 确定指數的符号
c = *s;
if ('\0' == c)
break;
if ('-' == c)
{
bNegativeExponent = true;
c = *s++;
}
else if ('+' == c)
{
bNegativeExponent = false;
c = *s++;
}
bMeetE = true;
}
else if (bDec)
{
bEInFirst = false;
// 小數部分
if (c >= '0' && c <= '9')
{
fDecimal += (c - '0') * fDecPower;
fDecPower = fDecPower * 0.1f;
}
else
{
break;
}
}
else
{
bEInFirst = false;
// 整數部分
if (c >= '0' && c <= '9')
{
fInteger = fInteger * 10.0f + c - '0';
}
else if (c == '.')
{
bDec = true;
}
else
{
break;
}
}
}
c = *s++;
}
// 指數處理
if (bMeetE)
{
float fExponent = bNegativeExponent ? 0.1f : 10.0f;
while (nIntegerExponent > 0)
{
fExponentData *= fExponent;
--nIntegerExponent;
}
}
// 溢出檢測
fResult = (bNegative? -(fInteger + fDecimal) : fInteger + fDecimal);
fResult *= fExponentData;
if (fResult > FLT_MAX)
{
fResult = FLT_MAX;
}
else if (fResult < -FLT_MAX)
{
fResult = -FLT_MAX;
}
else if (fResult > 0 && fResult < FLT_MIN)
{
fResult = FLT_MIN;
}
else if (fResult < 0 && fResult > -FLT_MIN)
{
fResult = -FLT_MIN;
}
return fResult;
}
// -------------------------------------------------------------------------
// 函數 : wtofloat
// 功能 : 将一個寬字元串轉換為浮點數
// 傳回值 : float
// 參數 : const wchar_t* s
// 附注 :
// -------------------------------------------------------------------------
float wtofloat(const wchar_t* s)
{
// check
if (!s)
return 0.0f;
float fResult = 0.0f; // 存儲結果
wchar_t c = 0;
// 整數部分
bool bNegative = false;
float fInteger = 0.0f;
// 小數部分
bool bDec = false;
float fDecimal = 0.0f;
float fDecPower = 0.1f;
// 指數部分
bool bMeetE = false;
bool bEInFirst = true; // e不能在最前面
bool bNegativeExponent = false;
unsigned int nIntegerExponent = 0;
float fExponentData = 1.0f;
c = *s++;
while (L' ' == c)
c = *s++; /* skip whitespace */
// 進行首位判斷,判斷是否是負數
if (L'-' == c)
{
bNegative = true;
c = *s++;
}
else if (L'+' == c)
{
bNegative = false;
c = *s++;
}
while (L'\0' != c)
{
if (bMeetE)
{
// 指數部分
if (c >= '0' && c <= '9')
{
nIntegerExponent = nIntegerExponent * 10 + c - '0';
}
else
{
break;
}
}
else
{
if ('e' == c || 'E' == c)
{
if (bEInFirst)
break;
// 确定指數的符号
c = *s;
if ('\0' == c)
break;
if ('-' == c)
{
bNegativeExponent = true;
c = *s++;
}
else if ('+' == c)
{
bNegativeExponent = false;
c = *s++;
}
bMeetE = true;
}
else if (bDec)
{
bEInFirst = false;
// 小數
if (c >= L'0' && c <= L'9')
{
fDecimal += (c - L'0') * fDecPower;
fDecPower = fDecPower * 0.1f;
}
else
{
return (bNegative? -(fInteger + fDecimal): fInteger + fDecimal);
}
}
else
{
bEInFirst = false;
// 整數
if (c >= L'0' && c <= L'9')
{
fInteger = fInteger * 10.0f + c - L'0';
}
else if (c == L'.')
{
bDec = true;
}
else
{
return (bNegative? -fInteger : fInteger);
}
}
}
c = *s++;
}
// 指數處理
if (bMeetE)
{
float fExponent = bNegativeExponent ? 0.1f : 10.0f;
while (nIntegerExponent > 0)
{
fExponentData *= fExponent;
--nIntegerExponent;
}
}
// 溢出檢測
fResult = (bNegative? -(fInteger + fDecimal) : fInteger + fDecimal);
fResult *= fExponentData;
if (fResult > FLT_MAX)
{
fResult = FLT_MAX;
}
else if (fResult < -FLT_MAX)
{
fResult = -FLT_MAX;
}
else if (fResult > 0 && fResult < FLT_MIN)
{
fResult = FLT_MIN;
}
else if (fResult < 0 && fResult > -FLT_MIN)
{
fResult = -FLT_MIN;
}
return fResult;
}
} // end NSUtil
// -------------------------------------------------------------------------
// $Log: $
測試代碼
float fffa = .0e-2;
fffa = 0e-2;
fffa = 1e-2;
fffa = 1e+1;
fffa = .1;
float ffff = atof("-545444.5e-10.67f");
ffff = atof("1e-10f");
ffff = atof("1e-");
ffff = atof("1e+");
ffff = atof("1e0");
float aaaa = NSUtil::atofloat("12.34");
aaaa = NSUtil::atofloat("1e-10f");
aaaa = NSUtil::atofloat("-545444.5e-10.67f");
aaaa = NSUtil::atofloat("1e-");
aaaa = NSUtil::atofloat("1e+");
aaaa = NSUtil::atofloat("1E+");
aaaa = NSUtil::atofloat("1e0");
aaaa = NSUtil::atofloat("-545444.5e-10");
aaaa = NSUtil::atofloat("-0.00000545444.5");
aaaa = NSUtil::atofloat("-54544444444444444444444444444444444444.5");
aaaa = NSUtil::atofloat("+1.345");
aaaa = NSUtil::atofloat(" -34.00001");
aaaa = NSUtil::atofloat(" -12.01001 ");
aaaa = NSUtil::atofloat(" 0.33344");
aaaa = NSUtil::atofloat("a23");
aaaa = NSUtil::atofloat("1234");
aaaa = NSUtil::atofloat("12.34");
aaaa = NSUtil::atofloat("12.34.56");
aaaa = NSUtil::atofloat(".34");
aaaa = NSUtil::atofloat("34a");
aaaa = NSUtil::atofloat("34a.456");
aaaa = NSUtil::atofloat("-34");
aaaa = NSUtil::atofloat("-56.34");
aaaa = NSUtil::atofloat("-3.45.67");
aaaa = NSUtil::atofloat("-.45.6a");
aaaa = NSUtil::atofloat("-.");
aaaa = NSUtil::atofloat("-0");
aaaa = NSUtil::atofloat("3.402823467e+38F");
aaaa = NSUtil::atofloat("-54544444444444444444444444444444444444.5");
aaaa = NSUtil::atofloat("5454444445444444444444444444444444444444.5");
aaaa = NSUtil::atofloat("0.0000000000000000000000000000000000000001");
aaaa = NSUtil::atofloat("-0.0000000000000000000000000000000000000001");
aaaa = NSUtil::strtofloatT("1e-10f");
aaaa = NSUtil::strtofloatT("-545444.5e-10.67f");
aaaa = NSUtil::strtofloatT("1e-");
aaaa = NSUtil::strtofloatT("1e+");
aaaa = NSUtil::strtofloatT("1e0");
aaaa = NSUtil::strtofloatT("+1.345");
aaaa = NSUtil::strtofloatT(" -34.00001");
aaaa = NSUtil::strtofloatT(" -12.01001 ");
aaaa = NSUtil::strtofloatT(L"1e-10f");
aaaa = NSUtil::strtofloatT(L"-545444.5e-10.67f");
aaaa = NSUtil::strtofloatT(L"1e-");
aaaa = NSUtil::strtofloatT(L"1e+");
aaaa = NSUtil::strtofloatT(L"1e0");
aaaa = NSUtil::strtofloatT(L"+1.345");
aaaa = NSUtil::strtofloatT(L" -34.00001");
aaaa = NSUtil::strtofloatT(L" -12.01001 ");
aaaa = NSUtil::wtofloat(L"1e-10f");
aaaa = NSUtil::wtofloat(L"-545444.5e-10.67f");
aaaa = NSUtil::wtofloat(L"1e-");
aaaa = NSUtil::wtofloat(L"1e+");
aaaa = NSUtil::wtofloat(L"1e0");
aaaa = NSUtil::wtofloat(L"+1.345");
aaaa = NSUtil::wtofloat(L" -34.00001");
aaaa = NSUtil::wtofloat(L" -12.01001 ");
aaaa = NSUtil::wtofloat(L" 0.33344");
aaaa = NSUtil::wtofloat(L"a23");
aaaa = NSUtil::wtofloat(L"1234");
aaaa = NSUtil::wtofloat(L"12.34");
aaaa = NSUtil::wtofloat(L"12.34.56");
aaaa = NSUtil::wtofloat(L".34");
aaaa = NSUtil::wtofloat(L"34a");
aaaa = NSUtil::wtofloat(L"34a.456");
aaaa = NSUtil::wtofloat(L"-34");
aaaa = NSUtil::wtofloat(L"-56.34");
aaaa = NSUtil::wtofloat(L"-3.45.67");
aaaa = NSUtil::wtofloat(L"-.45.6a");
aaaa = NSUtil::wtofloat(L"-.");
aaaa = NSUtil::wtofloat(L"-0");
<script type="text/javascript" src="http://js.tongji.linezing.com/3587820/tongji.js"></script>