讓學生寫的自己版本的atof()

//============================================================
//  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;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章