⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wytimespec_strnum.cpp

📁 一个不错
💻 CPP
字号:
/* Copyright is licensed under GNU LGPL.                 by I.J.Wang 2003*/#define WYLIB_SOURCE#include "wytimespec.h"#include "wy__scanum.h"#include <cstdlib>// [Internal] Provide common functions for _strnum(WyTimeSpec&,..)//class Wy__P10 {  public:     static const size_t MaxP10=18;  private:    typedef signed long long value_type;   // better able to hold all precision    static const int GiDig10=WyTimeSpec::_GigaDigit10;    static const value_type Giga=WY_CONST_GIGA;    // 1x10^9    static const value_type p10tab[MaxP10+1];  public:    // [Syn] Get power of 10    //     //  Note: use MaxP10 for limit of exp    //     // [Ret] 10^exp    //    inline static value_type p10(int exp)         { return p10tab[exp]; };    // [Syn] Convert input number (taken as num/10^exp10) to    //       another representation, as follows:    //    //       Let input_number= num/10^exp10, then upon returned,    //       res1= input_number/Giga    //       res2= input_number%Giga    //    //       Note: result value less than 1/Giga is ignored    //    // [Ret] Ok    //       Wym_EBADMSG  exp10>MaxP10+GiDig10 (for cooperate with _strnum)    //       Wym_ERANGE   overflow occurred in operation     //    static WyRet norm_nano(value_type& res1, value_type& res2,                           value_type num, int exp10)         {           if((std::numeric_limits<value_type>::max()!=                          std::numeric_limits<long long>::max())||              (std::numeric_limits<value_type>::min()!=                          std::numeric_limits<long long>::min())) {              WY_TERMINATE("");  // as lldiv_t is used, check for signed long long.           }           if(exp10<0) {             if(exp10>=-GiDig10) {               std::lldiv_t dt;               WyRet r;               value_type tmp;               const size_t ddp=GiDig10+exp10;               if(ddp>Wy__P10::MaxP10) {                 // assertion failed (GiDig10<Wy__P10::MaxP10)                 WY_THROW(WyRet(Wym_ERANGE));                }               if((r=Wy::wy_mul(tmp,num,p10tab[ddp]))!=Ok) {                 WY_RETURN(r);               }               dt=std::lldiv(tmp,Giga);               res1=dt.quot;               res2=dt.rem;             } else if(exp10>=-(int)MaxP10) {               const size_t ddp=-exp10-GiDig10;               std::lldiv_t dt;               if(ddp>MaxP10) {                 WY_RETURN(Wym_EBADMSG);               }               dt=std::lldiv(num,p10tab[ddp]);               res1=0;               res2=dt.quot;  // dt.rem ignored             } else {               res1=res2=0;             }           } else {             WyRet r;             value_type tmp;             if(exp10>(int)MaxP10) {               WY_RETURN(Wym_EBADMSG);             }             if((r=Wy::wy_mul(tmp,num,p10tab[exp10]))!=Ok) {               WY_RETURN(r);             }             res1=tmp;             res2=0;           }           return(Ok);         };};const Wy__P10::value_type Wy__P10::p10tab[MaxP10+1]={ 1LL,10LL,100LL,1000LL,10000LL,100000LL,1000000LL, 10000000LL, // 10^0 - 10^7  100000000LL,          // 10^8  1000000000LL,         // 10^9  10000000000LL,        // 10^10  100000000000LL,       // 10^11  1000000000000LL,      // 10^12  10000000000000LL,     // 10^13  100000000000000LL,    // 10^14  1000000000000000LL,   // 10^15  10000000000000000LL,  // 10^16  100000000000000000LL, // 10^17  1000000000000000000LL // 10^18};// S::= S1|S2|S3// S1::= [+-]ddd[<Exp>]// S2::= [+-].ddd[<Exp>]// S3::= [+-]ddd.[ddd][<Exp>]// Exp::= [Ee][+-]ddd//// Wym_EBADMSG   failed processing string representation//WyRet Wy::_strnum(WyTimeSpec& res, const char** endptr, WyCSeg cseg){ typedef long long TmpInt;   // better able to hold all precision const int Radix=10; TmpInt ll_sec; TmpInt ll_nsec; int exptv_nsec;   const char* cptr; size_t clft; WyRet r( Wy::wy_strnum2(ll_sec,ll_nsec,exptv_nsec,&cptr,cseg.begin(),cseg.size()) ); // SRC_NUM= ll_sec + ll_nsec*10^exptv_nsec (exptv_nsec<=0) // if(r==Ok) {   if(endptr!=0) {     *endptr=cptr;   }   if((ll_sec>(TmpInt)std::numeric_limits<Wy_Second>::max())||      (ll_sec<(TmpInt)std::numeric_limits<Wy_Second>::min())) {     WY_RETURN(Wym_ERANGE);   }   // normalize ll_nsec   TmpInt tmp;   if((r=Wy__P10::norm_nano(tmp, ll_nsec,ll_nsec,exptv_nsec))!=Ok) {     WY_RETURN(r);   }   if(tmp!=0) {     // assertion failed     WY_THROW(WyRet(Wym_ERANGE));   }   if((ll_nsec>=TmpInt(WY_CONST_GIGA))||      (ll_nsec<=-TmpInt(WY_CONST_GIGA))) {     // assertion failed     WY_THROW(WyRet(Wym_ERANGE));   }   // S= [+-]ddd[.ddd]   //  = [+-]ddd.   //  = [+-].ddd   WY_RETURN( res.reset(Wy_Second(ll_sec),Wy_Nano(ll_nsec)) ); } if(r!=Wym_EBADMSG) {   if(endptr!=0) {     *endptr=cptr;   }   WY_RETURN(r); } clft=cseg.size()-(cptr-cseg.begin()); if(clft<2) {   if(endptr!=0) {     *endptr=cptr;   }   WY_RETURN(Wym_EBADMSG); } if((*cptr!='e')&&(*cptr!='E')) {   if(endptr!=0) {     *endptr=cptr;   }   if((ll_sec>(TmpInt)std::numeric_limits<Wy_Second>::max())||      (ll_sec<(TmpInt)std::numeric_limits<Wy_Second>::min())) {     WY_RETURN(Wym_ERANGE);   }   // normalize ll_nsec   TmpInt tmp;   if((r=Wy__P10::norm_nano(tmp, ll_nsec,ll_nsec,exptv_nsec))!=Ok) {     WY_RETURN(r);   }   if(tmp!=0) {     // assertion failed     WY_THROW(WyRet(Wym_ERANGE));   }   if((ll_nsec>=TmpInt(WY_CONST_GIGA))||      (ll_nsec<=-TmpInt(WY_CONST_GIGA))) {     // assertion failed     WY_THROW(WyRet(Wym_ERANGE));   }   // S= [+-]ddd[.ddd]   //  = [+-]ddd.   //  = [+-].ddd   if((r=res.reset(Wy_Second(ll_sec),Wy_Nano(ll_nsec)))!=Ok) {     WY_RETURN(r);   }   WY_RETURN(Wym_EBADMSG); } const char* const ptr_exp(cptr); --clft; ++cptr; int tt_exp; r=Wy::_strnum(tt_exp,&cptr,WyCSeg(cptr,clft),Radix); const WyRet r_exp(r); if(r!=Ok) {   if(endptr!=0) {     *endptr=ptr_exp;   }   if((r==Wym_ERANGE)||(r==Wym_ENOENT)) do {     // stop at ptr_exp     if((ll_sec>(TmpInt)std::numeric_limits<Wy_Second>::max())||        (ll_sec<(TmpInt)std::numeric_limits<Wy_Second>::min())) {       WY_RETURN(Wym_ERANGE);     }     // normalize ll_nsec     TmpInt tmp;     if((r=Wy__P10::norm_nano(tmp, ll_nsec,ll_nsec,exptv_nsec))!=Ok) {       break;     }     if(tmp!=0) {       // assertion failed       WY_THROW(WyRet(Wym_ERANGE));     }     if((ll_nsec>=TmpInt(WY_CONST_GIGA))||        (ll_nsec<=-TmpInt(WY_CONST_GIGA))) {       // assertion failed       WY_THROW(WyRet(Wym_ERANGE));     }     // S= [+-]ddd[.ddd]     //  = [+-]ddd.     //  = [+-].ddd     if((r=res.reset(Wy_Second(ll_sec),Wy_Nano(ll_nsec)))!=Ok) {       WY_RETURN(r);     }     if(r_exp==Wym_ENOENT) {       WY_RETURN( Wym_EBADMSG);     }     WY_RETURN( Wym_ERANGE );   } while(false);   // FALLTHROW (Wym_EBADMSG) } if(endptr!=0) {   *endptr=cptr; }  // SRC_NUM= (ll_sec + ll_nsec*10^exptv_nsec)*10^tt_exp   (exptv_nsec<=0) // if(tt_exp>=0) {   if(tt_exp>(int)Wy__P10::MaxP10) {     WY_RETURN(Wym_ERANGE);   }   TmpInt tmp;   if((r=Wy::wy_mul(ll_sec,ll_sec,Wy__P10::p10(tt_exp)))!=Ok) {     WY_RETURN(r);   }   if((r=Wy__P10::norm_nano(tmp,ll_nsec,ll_nsec,exptv_nsec+tt_exp))!=Ok) {     WY_RETURN(r);   }   if((r=Wy::wy_add(ll_sec,ll_sec,tmp))!=Ok) {     WY_RETURN(r);   }   if((ll_sec>(TmpInt)std::numeric_limits<Wy_Second>::max())||      (ll_sec<(TmpInt)std::numeric_limits<Wy_Second>::min())) {     WY_RETURN(Wym_ERANGE);   }   if((r=res.reset(Wy_Second(ll_sec),Wy_Nano(ll_nsec)))!=Ok) {     WY_RETURN(r);   }   WY_RETURN(r_exp); } else {   const int tt_exp_abs=-tt_exp;   TmpInt tmp;   if(tt_exp_abs>(int)Wy__P10::MaxP10) {     WY_RETURN(Wym_ERANGE);   }   std::lldiv_t dt=std::lldiv(ll_sec,Wy__P10::p10(tt_exp_abs));   ll_sec=dt.quot;   {     const int dpp=-exptv_nsec;     if(dpp>(int)Wy__P10::MaxP10) {       WY_RETURN(Wym_EBADMSG);     }     if((r=Wy::wy_mul(tmp,dt.rem,Wy__P10::p10(dpp)))!=Ok) {       WY_RETURN(r);     }   }   if((r=Wy::wy_add(tmp,tmp,ll_nsec))!=Ok) {     WY_RETURN(r);   }   if((r=Wy__P10::norm_nano(tmp,ll_nsec,tmp,tt_exp+exptv_nsec))!=Ok) {     WY_RETURN(r);   }   if((r=Wy::wy_add(ll_sec,ll_sec,tmp))!=Ok) {     WY_RETURN(r);   }   if((ll_sec>(TmpInt)std::numeric_limits<Wy_Second>::max())||      (ll_sec<(TmpInt)std::numeric_limits<Wy_Second>::min())) {     WY_RETURN(Wym_ERANGE);   }   if((r=res.reset(Wy_Second(ll_sec),Wy_Nano(ll_nsec)))!=Ok) {     WY_RETURN(r);   }   WY_RETURN(r_exp); }};WyRet Wy::_strnum(WyTimeSpec& res, const char** endptr, WyCSeg cseg, const int& radix){  if((radix!=10)&&(radix!=0)) {    WY_RETURN( Wym_EINVAL );  }  return _strnum(res,endptr,cseg); };WyRet Wy::_strnum(WyTimeSpec& res, const char** endptr, WyCSeg cseg, int& radix){  if(radix!=10) {    if(radix!=0) {      WY_RETURN( Wym_EINVAL );    }    radix=10;  }  return _strnum(res,endptr,cseg); };WyRet Wy::_scanum(WyTimeSpec& n, size_t& idx, const WyCSeg& text, const int& radix){ return wy__scanum(n,idx,text,radix); };WyRet Wy::_scanum(WyTimeSpec& n, size_t& idx, const WyCSeg& text){ return wy__scanum(n,idx,text,0); };

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -