📄 wy__num.h
字号:
/* Copyright is licensed under GNU LGPL. by I.J.Wang 2004 Basci conversions between ascii-string and integral type*/#ifndef WY__NUM_H__#define WY__NUM_H__#include "wyret.h"#include "wycseg.h"#include <limits>namespace Wy { inline int _charnum(int ch) WY__TSPC() { if(ch<='9') { if(ch<'0') { return(-1); } return(ch-'0'); } else if(ch>='a') { if(ch>'z') { return(-1); } return(ch-'a'+int(10)); } else if(ch>='A') { if(ch>'Z') { return(-1); } return(ch-'A'+int(10)); } else { return(-1); } };// Declaration of _strnum of all supported built-in types:// char, // signed(char, short, int, long , long long)// unsigned(char, short, int, long , long long)// float, double/*WyRet _strnum(char& res, const char** endptr, const char* buf, size_t blen, const int& radix);WyRet _strnum(signed char& res, const char** endptr, const char* buf, size_t blen, const int& radix);WyRet _strnum(signed short& res, const char** endptr, const char* buf, size_t blen, const int& radix);WyRet _strnum(signed int& res, const char** endptr, const char* buf, size_t blen, const int& radix);WyRet _strnum(signed long& res, const char** endptr, const char* buf, size_t blen, const int& radix);WyRet _strnum(signed long long& res, const char** endptr, const char* buf, size_t blen, const int& radix);WyRet _strnum(unsigned char& res, const char** endptr, const char* buf, size_t blen, const int& radix);WyRet _strnum(unsigned short& res, const char** endptr, const char* buf, size_t blen, const int& radix);WyRet _strnum(unsigned int& res, const char** endptr, const char* buf, size_t blen, const int& radix);WyRet _strnum(unsigned long& res, const char** endptr, const char* buf, size_t blen, const int& radix);WyRet _strnum(unsigned long long& res, const char** endptr, const char* buf, size_t blen, const int& radix);WyRet _strnum(float& res, const char** endptr, const char* buf,size_t blen, const int& radix);WyRet _strnum(double& res, const char** endptr, const char* buf,size_t blen, const int& radix);*/WyRet _strnum(char& res, const char** endptr, WyCSeg cseg, const int& radix);WyRet _strnum(signed char& res, const char** endptr, WyCSeg cseg, const int& radix);WyRet _strnum(signed short& res, const char** endptr, WyCSeg cseg, const int& radix);WyRet _strnum(signed int& res, const char** endptr, WyCSeg cseg, const int& radix);WyRet _strnum(signed long& res, const char** endptr, WyCSeg cseg, const int& radix);WyRet _strnum(signed long long& res, const char** endptr, WyCSeg cseg, const int& radix);WyRet _strnum(unsigned char& res, const char** endptr, WyCSeg cseg, const int& radix);WyRet _strnum(unsigned short& res, const char** endptr, WyCSeg cseg, const int& radix);WyRet _strnum(unsigned int& res, const char** endptr, WyCSeg cseg, const int& radix);WyRet _strnum(unsigned long& res, const char** endptr, WyCSeg cseg, const int& radix);WyRet _strnum(unsigned long long& res, const char** endptr, WyCSeg cseg, const int& radix);WyRet _strnum(float& res, const char** endptr, WyCSeg cseg, const int& radix);WyRet _strnum(double& res, const char** endptr, WyCSeg cseg, const int& radix);///*WyRet _strnum(char& res, const char** endptr, const char* buf, size_t blen, int& radix);WyRet _strnum(signed char& res, const char** endptr, const char* buf, size_t blen, int& radix);WyRet _strnum(signed short& res, const char** endptr, const char* buf, size_t blen, int& radix);WyRet _strnum(signed int& res, const char** endptr, const char* buf, size_t blen, int& radix);WyRet _strnum(signed long& res, const char** endptr, const char* buf, size_t blen, int& radix);WyRet _strnum(signed long long& res, const char** endptr, const char* buf, size_t blen, int& radix);WyRet _strnum(unsigned char& res, const char** endptr, const char* buf, size_t blen, int& radix);WyRet _strnum(unsigned short& res, const char** endptr, const char* buf, size_t blen, int& radix);WyRet _strnum(unsigned int& res, const char** endptr, const char* buf, size_t blen, int& radix);WyRet _strnum(unsigned long& res, const char** endptr, const char* buf, size_t blen, int& radix);WyRet _strnum(unsigned long long& res, const char** endptr, const char* buf, size_t blen, int& radix);WyRet _strnum(float& res, const char** endptr, const char* buf,size_t blen, int& radix);WyRet _strnum(double& res, const char** endptr, const char* buf,size_t blen, int& radix);*/WyRet _strnum(char& res, const char** endptr, WyCSeg cseg, int& radix);WyRet _strnum(signed char& res, const char** endptr, WyCSeg cseg, int& radix);WyRet _strnum(signed short& res, const char** endptr, WyCSeg cseg, int& radix);WyRet _strnum(signed int& res, const char** endptr, WyCSeg cseg, int& radix);WyRet _strnum(signed long& res, const char** endptr, WyCSeg cseg, int& radix);WyRet _strnum(signed long long& res, const char** endptr, WyCSeg cseg, int& radix);WyRet _strnum(unsigned char& res, const char** endptr, WyCSeg cseg, int& radix);WyRet _strnum(unsigned short& res, const char** endptr, WyCSeg cseg, int& radix);WyRet _strnum(unsigned int& res, const char** endptr, WyCSeg cseg, int& radix);WyRet _strnum(unsigned long& res, const char** endptr, WyCSeg cseg, int& radix);WyRet _strnum(unsigned long long& res, const char** endptr, WyCSeg cseg, int& radix);WyRet _strnum(float& res, const char** endptr, WyCSeg cseg, int& radix);WyRet _strnum(double& res, const char** endptr, WyCSeg cseg, int& radix);inline WyRet _strnum(char& res, const char** endptr, WyCSeg cseg){ return _strnum(res,endptr,cseg,10); };inline WyRet _strnum(signed char& res, const char** endptr, WyCSeg cseg){ return _strnum(res,endptr,cseg,10); };inline WyRet _strnum(signed short& res, const char** endptr, WyCSeg cseg){ return _strnum(res,endptr,cseg,10); };inline WyRet _strnum(signed int& res, const char** endptr, const WyCSeg& cseg){ return _strnum(res,endptr,cseg,10); };inline WyRet _strnum(signed long& res, const char** endptr, WyCSeg cseg){ return _strnum(res,endptr,cseg,10); };inline WyRet _strnum(signed long long& res, const char** endptr, WyCSeg cseg){ return _strnum(res,endptr,cseg,10); };inline WyRet _strnum(unsigned char& res, const char** endptr, WyCSeg cseg){ return _strnum(res,endptr,cseg,10); };inline WyRet _strnum(unsigned short& res, const char** endptr, WyCSeg cseg){ return _strnum(res,endptr,cseg,10); };inline WyRet _strnum(unsigned int& res, const char** endptr, WyCSeg cseg){ return _strnum(res,endptr,cseg,10); };inline WyRet _strnum(unsigned long& res, const char** endptr, WyCSeg cseg){ return _strnum(res,endptr,cseg,10); };inline WyRet _strnum(unsigned long long& res, const char** endptr, WyCSeg cseg){ return _strnum(res,endptr,cseg,10); };WyRet _strnum(float& res, const char** endptr, WyCSeg cseg);WyRet _strnum(double& res, const char** endptr, WyCSeg cseg);//WyRet wy_strnum2(signed int& res1, signed int& res2, int& fdig, const char** endptr, const char* buf,size_t blen);WyRet wy_strnum2(signed long& res1, signed long& res2, int& fdig, const char** endptr, const char* buf,size_t blen);WyRet wy_strnum2(signed long long& res1, signed long long& res2, int& fdig, const char** endptr, const char* buf,size_t blen);WyRet wy_strnum3(signed int& res1, signed int& res2, int& fdig, int& res3, const char** endptr, const char* buf,size_t blen);WyRet wy_strnum3(signed long& res1, signed long& res2, int& fdig, int& res3, const char** endptr, const char* buf,size_t blen);WyRet wy_strnum3(signed long long& res1, signed long long& res2, int& fdig, int& res3, const char** endptr, const char* buf,size_t blen);// [Syn] Range checked multiplication// The result of n1*n2 is stored into res//// [Ret] Ok// Wym_ERANGE//template <typename NumT>WyRet wy_mul(NumT& res, NumT n1, NumT n2){ if(std::numeric_limits<NumT>::is_exact) { const NumT tmp(n1*n2); if(n1!=0) { if((tmp/n1)!=n2) { WY_RETURN(Wym_ERANGE); } } else if(n2!=0) { if((tmp/n2)!=n1) { WY_RETURN(Wym_ERANGE); } } else {}; res=tmp; } else { WY_TERMINATE(""); // in case } return(Ok);};// [Syn] Range checked addition// The result of n1+n2 is stored into res//// [Ret] Ok// Wym_ERANGE//template <typename NumT>WyRet wy_add(NumT& res, NumT n1, NumT n2){ if(std::numeric_limits<NumT>::is_signed) { const NumT tmp(n1+n2); if(n1<=NumT(0)) { if(tmp>n2) { WY_RETURN(Wym_ERANGE); } } else { if(tmp<=n2) { WY_RETURN(Wym_ERANGE); } } res=tmp; } else { const NumT tmp(n1+n2); if(tmp<n2) { WY_RETURN(Wym_ERANGE); } res=tmp; } return(Ok);};WyRet _scanum(char&, size_t&, const WyCSeg&, const int&);WyRet _scanum(signed char&, size_t&, const WyCSeg&, const int&);WyRet _scanum(signed short int&, size_t&, const WyCSeg&, const int&);WyRet _scanum(signed int&, size_t&, const WyCSeg&, const int&);WyRet _scanum(signed long int&, size_t&, const WyCSeg&, const int&);WyRet _scanum(signed long long int&, size_t&, const WyCSeg&, const int&);WyRet _scanum(unsigned char&, size_t&, const WyCSeg&, const int&);WyRet _scanum(unsigned short int&, size_t&, const WyCSeg&, const int&);WyRet _scanum(unsigned int&, size_t&, const WyCSeg&, const int&);WyRet _scanum(unsigned long int&, size_t&, const WyCSeg&, const int&);WyRet _scanum(unsigned long long int&, size_t&, const WyCSeg&, const int&);WyRet _scanum(float&, size_t&, const WyCSeg&, const int&);WyRet _scanum(double&, size_t&, const WyCSeg&, const int&);WyRet _scanum(char&, size_t&, const WyCSeg&);WyRet _scanum(signed char&, size_t&, const WyCSeg&);WyRet _scanum(signed short int&, size_t&, const WyCSeg&);WyRet _scanum(signed int&, size_t&, const WyCSeg&);WyRet _scanum(signed long int&, size_t&, const WyCSeg&);WyRet _scanum(signed long long int&, size_t&, const WyCSeg&);WyRet _scanum(unsigned char&, size_t&, const WyCSeg&);WyRet _scanum(unsigned short int&, size_t&, const WyCSeg&);WyRet _scanum(unsigned int&, size_t&, const WyCSeg&);WyRet _scanum(unsigned long int&, size_t&, const WyCSeg&);WyRet _scanum(unsigned long long int&, size_t&, const WyCSeg&);WyRet _scanum(float&, size_t&, const WyCSeg&);WyRet _scanum(double&, size_t&, const WyCSeg&);}; // End of Wy// [Internal] Convert digit characters in buf[blen] denoting a positive number//// Assert: endptr!=NULL// 2<=radix<=36// buf!=0//// [Ret] 1. *endptr-buf = characters recognized as number notation// 2. res = stored with the resultant number of [buf,*endptr)// or zero, if no valid digits)// // Ok// Wym_ERANGE Result would be unrepresentable// Wym_EBADMSG Invalid digit encountered// Wym_ENOENT No number notation recognized//template <typename NumType>inline WyRet wy__strnum_pos(NumType& res, const char** endptr, const char* buf, size_t blen,int radix){ static const NumType MultMax=std::numeric_limits<NumType>::max()/radix; static const NumType MaxNum=std::numeric_limits<NumType>::max(); const char* sptr(buf); if(std::numeric_limits<NumType>::is_integer) { res=0; size_t idx(0); for( ; idx<blen; ++idx,++sptr) { const int d0= Wy::_charnum(*sptr); if((d0<0)||(d0>=radix)) { if(endptr!=NULL) { *endptr=sptr; } if(idx==0) { WY_RETURN( Wym_ENOENT ); } WY_RETURN( Wym_EBADMSG ); } if(res>MultMax) { if(endptr!=NULL) { *endptr=sptr; } // assert idx>0 WY_RETURN( Wym_ERANGE ); } const NumType tmp1=res*radix; if(tmp1>MaxNum-d0) { if(endptr!=NULL) { *endptr=sptr; } // assert idx>0 WY_RETURN( Wym_ERANGE ); } res=tmp1+d0; } if(endptr!=NULL) { *endptr=sptr; } if(idx==0) { WY_RETURN( Wym_ENOENT ); } return(Ok); }};// [Internal] Convert digit characters in buf[blen] denoting a negative number//// Assert: endptr!=NULL// 2<=radix<=36// buf!=0// NumType provide std::numeric_limits<T>::is_signed test//// [Ret] 1. *endptr-buf = characters recognized as number notation// 2. res = stored with the resultant number of [buf,*endptr)// or zero, if no valid digits)// // Ok// Wym_ERANGE Result would be unrepresentable// Wym_EBADMSG Invalid digit encountered// Wym_ENOENT No number notation recognized//template <typename NumType>inline WyRet wy__strnum_neg(NumType& res, const char** endptr, const char* buf, size_t blen, int radix){ static const NumType MultMin=std::numeric_limits<NumType>::min()/radix; static const NumType MinNum=std::numeric_limits<NumType>::min(); const char* sptr(buf); if(std::numeric_limits<NumType>::is_integer) { res=0; size_t idx(0); for( ; idx<blen; ++idx,++sptr) { const int d0= Wy::_charnum(*sptr); if((d0<0)||(d0>=radix)) { if(endptr!=NULL) { *endptr=sptr; } if(idx==0) { WY_RETURN( Wym_ENOENT ); } WY_RETURN( Wym_EBADMSG ); } if(res<MultMin) { if(endptr!=NULL) { *endptr=sptr; } // assert idx>0 WY_RETURN( Wym_ERANGE ); } const NumType tmp1=res*radix; if(tmp1<MinNum+d0) { if(endptr!=NULL) { *endptr=sptr; } // assert idx>0 WY_RETURN( Wym_ERANGE ); } res=tmp1-d0; } if(endptr!=NULL) { *endptr=sptr; } if(idx==0) { WY_RETURN( Wym_ENOENT ); } return(Ok); }};// [Syn] Convert float number string notation in the form:// S1::= [+-]ddd// S2::= [+-].ddd// S3::= [+-]ddd.[ggg]// to two numbers, res1 stored with result of the string before '.'// res2 stored with result of the string after '.'// fdig stored with the negative number of digits of the fraction part of// buf, so (res2*10^fdig) always less than 0. And note that if res2 is // zero,// frdig may not be zero.// derives the real fraction part of the number// fdig<=0// Note: Sign relation of res1 and res2 are as follows:// 1. (res1>0)&&(res2>=0)// 2. (res1<0)&&(res2<=0)// 3. (res1==0)&&((res2>=0)||(res2<0))//// [Ret] Ok// Wym_EBADMSG// Wym_ERANGE// Wym_ENOENT//template <typename ResType1, typename ResType2>WyRet wy__strnum2(ResType1& res1, ResType2& res2, int& fdig,const char** endptr, const char* buf,size_t blen)try { const int Radix=10; WyRet r; const char* cptr; size_t clft; res1=ResType1(0); res2=ResType2(0); fdig=0; if(blen<=0) { if(endptr!=NULL) { *endptr=buf; } WY_RETURN( Wym_ENOENT ); } if((r=Wy::_strnum(res1,&cptr,WyCSeg(buf,blen),Radix))==Ok) { // buf=[+-]ddd if(cptr-buf!=int(blen)) { WY_THROW( WyRet() ); // assertion fail } if(endptr!=NULL) { *endptr=cptr; } return(Ok); } if((r!=Wym_EBADMSG)&&(r!=Wym_ENOENT)) { if(endptr!=NULL) { *endptr=cptr; } WY_RETURN(r); } if(*cptr!='.') { if(endptr!=NULL) { *endptr=cptr; } WY_RETURN(r); // Wym_EBADMSG or Wym_ENOENT } const char* const FracPtr=cptr+1; // point to first character of fraction if(cptr==buf) { // buf=.xxx ++cptr; clft=blen-(cptr-buf); if(clft<=0) { if(endptr!=NULL) { *endptr=buf; } WY_RETURN(Wym_ENOENT); // buf="." } const int tmp(Wy::_charnum(*cptr)); if((tmp<0)||(tmp>=Radix)) { if(endptr!=NULL) { *endptr=buf; } WY_RETURN(Wym_ENOENT); // fraction does not start with a digit
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -