//============================================================
// week 8, 額外的:如何將字符串轉化爲一個浮點數
//
atof_s(...)
// 如 “-12.345” -> 12.345
//
"FF" -> 255 ( 16進制)
//
//
本程序不靠慮0x之類的數據標示頭!
// X. Zhang, SEU
//============================================================
#include
#include
using namespace std;
#define IS_DOT(c)
(c == '.')
#define IS_DIGIT(c)
((c>='0') && (c<='9'))
#define IS_DIGIT_EX_BIG(c) ((c>='A')
&& (c<='F'))
#define IS_DIGIT_EX_SMALL(c) ((c>='a') &&
(c<='f'))
#define VALID_CHAR(c) (
IS_DIGIT(c) || \
IS_DIGIT_EX_BIG(c) || \
IS_DIGIT_EX_SMALL(c) ||\
IS_DOT(c))
inline bool CharToN(int& digit, const char c,int
JINGZHI=10)
{
if(JINGZHI <=0 )
{
return false;
}
if(IS_DIGIT(c))
{
digit = c-'0';
}
else if(IS_DIGIT_EX_BIG(c))
{
digit = c - 'A' + 10;
}
else if(IS_DIGIT_EX_SMALL(c))
{
digit = c -'a' + 10;
}
else
{
return false;
}
if(( digit >= 0) && ( digit < JINGZHI))
{
return true;
}
return false;
}
int strlen_s(const char* s) // our version of strlen
{
int i_size = 0;
for(;s[i_size];
i_size++);
return
i_size;
}
//============================================================
// 調用這個函數,將"12345" -> 0.12345
//
將"789" -> 0.789
//
將"0098" -> 0.0098
// 本函數是輔助函數,是爲了atof_s()碰到小數點後
//
處理後面的所有字符
//============================================================
double fraction_value(const char* s,int JINGZHI=10)
{
double sum = 0;
double DIVID = 1.0;
int digit = 0;
int N =
strlen_s(s);
for(int i = 0; i < N;
i ++)
{
if( ! CharToN(digit,s[i],JINGZHI))
{
break;
}
DIVID *= JINGZHI;
sum = sum + digit/DIVID;
}
return sum;
}
//=====================================================
// transfer to a double data
//
爲了簡化邏輯,裏面用了goto
//====================================================
double atof_s(const char s[],int JINGZHI = 10)
{
int N = strlen_s(s);
int digit = 0;
double sum = 0;
bool if_minus =0;
bool sign_handled = false; // if we have
handled +/-
for(int i = 0; i < N; i ++)
{
if(!sign_handled)
{
switch(s[i])
{
case ' ':
case '\t':
case '\n':
case '\r':
break;
case '+':
if_minus = false;
sign_handled = true;
break;
case '-':
if_minus = true;
sign_handled = true;
break;
default:
if(VALID_CHAR(s[i]))
{
if_minus = false;
sign_handled = true;
i --; // we do not handle it in this logic, so i--
// let
it be handled in big-else case
}
else
{
// bad char now, we can quit!
goto EXIT;
}
}
}
else if(IS_DOT(s[i]))
{
// 只要碰到小數點,後面的計算全部在下面這個函數中進行
sum +=
fraction_value(s+i+1,JINGZHI);
break;
}
else
{
if(CharToN(digit,s[i],JINGZHI))
{
sum = sum * JINGZHI +
digit;
}
else
{
break;
}
}
}
EXIT:
if(if_minus)
{
sum = - sum;
}
return sum;
}
int main()
{
cout<<"atof_s(\"
-1234567.09012\",10)="<<setprecision(15)<<atof_s("
-1234567.09012")<<endl;
cout<<"atof_s(\"-EA08.0FFABCDF\",16)="<<setprecision(15)<<atof_s("-EA08.0FFABCDF",16)<<endl;
cout<<"atof_s(\"-.09012\",10)="<<setprecision(10)<<atof_s("-.09012",10)<<endl;
cout<<"atof_s(\"+.09012\")="<<setprecision(10)<<atof_s("+.09012")<<endl;
cout<<"atof_s(\"+.09F12\",16)="<<setprecision(10)<<atof_s("+.09F12",16)<<endl;
cout<<"atof_s(\"FF\",16)="<<setprecision(10)<<atof_s("FF",16)<<endl;
return 0;
}
//////////////////////////////////////////////////////////////////////////////////////////////////