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

📄 ck_math.cpp

📁 一个不错
💻 CPP
字号:
#include "wymath.h"#include "wy__math.h"#include "wystr.h"#include <iostream>#include <stdlib.h>#include <stdio.h>static const double ErrRate_Sci=1e-13;   // error ratio limit of _scifstatic const double ErrRate_Float=1e-18;struct ChkSmpDouble {   const char* nstr;   size_t slen;   double ans;   void verify(void)        {         const int PrecisionDigits=14;         const double MaxErrRat=std::pow(10.0,-PrecisionDigits);         WyRet r;         const char* cptr;         double res;         if((r=Wy::_strnum(res,&cptr,WyCSeg(nstr,slen)))!=Ok) {           WY_THROW(r);         }         if(cptr-nstr!=(int)slen) {           WY_THROW( WyRet() );         }         if(ans!=0.0) {           const double err_rat=std::fabs((res-ans)/ans);           if(err_rat>MaxErrRat) {             std::cerr.precision(PrecisionDigits+2);             std::cerr << "ans=" << ans << ", res=" << res                        << ". error ratio=" << err_rat << std::endl;             WY_THROW( WyRet() );           }         } else {           if(std::fabs(res)>MaxErrRat) {             std::cerr.precision(PrecisionDigits+2);             std::cerr << "ans=" << ans << ", res=" << res << std::endl;             WY_THROW( WyRet() );           }         }        };};struct ChkSmpFloat {   typedef float CkType;   const char* nstr;   size_t slen;   double ans;   void verify(void)        {         const int PrecisionDigits=7;         const double MaxErrRat=std::pow(10.0,-PrecisionDigits);         WyRet r;         const char* cptr;         CkType res;         if((r=Wy::_strnum(res,&cptr,WyCSeg(nstr,slen)))!=Ok) {           WY_THROW(r);         }         if(cptr-nstr!=(int)slen) {           WY_THROW( WyRet() );         }         if(ans!=0.0) {           const double err_rat=std::fabs((res-ans)/ans);           if(err_rat>MaxErrRat) {             std::cerr.precision(PrecisionDigits+2);             std::cerr << "ans=" << ans << ", res=" << res                        << ". error ratio=" << err_rat << std::endl;             WY_THROW( WyRet() );           }         } else {           if(std::fabs(res)>MaxErrRat) {             std::cerr.precision(PrecisionDigits+2);             std::cerr << "ans=" << ans << ", res=" << res << std::endl;             WY_THROW( WyRet() );           }         }        };};static void t_strnum(void){ ChkSmpDouble chk_dtab[]={   {".0",2,0.0},   {".00",3,0.0},   {"1",1,1.0},   {"0.045600",8,0.0456},   {"00.045600",9,0.0456},{".045600",7,0.0456},   {"1e2",3,100.0},   {"-23.456",7,-23.456},   {"23.456e-1",9,2.3456},   {".123456789e0",12,0.123456789},   {".123456789e-1",13,0.123456789e-1},   {".123456789e-2",13,0.123456789e-2},   {".123456789e-3",13,0.123456789e-3},   {".123456789e-4",13,0.123456789e-4},   {".123456789e-5",13,0.123456789e-5},   {".123456789e-300",15,0.123456789e-300},   {".123456789e-301",15,0.123456789e-301},   {".123456789012345678e0",21,0.123456789012345678},   {".12345678901234567e-1",21,0.12345678901234567e-1},   {".12345678901234567e-2",21,0.12345678901234567e-2},   {".12345678901234567e-3",21,0.12345678901234567e-3},   {".12345678901234567e-4",21,0.12345678901234567e-4},   {".12345678901234567e-5",21,0.12345678901234567e-5},   {".12345678901234567e+1",21,0.12345678901234567e+1},   {".12345678901234567e+2",21,0.12345678901234567e+2},   {".12345678901234567e+3",21,0.12345678901234567e+3},   {".12345678901234567e+4",21,0.12345678901234567e+4},   {".12345678901234567e+5",21,0.12345678901234567e+5},   {".12345678901234567e+300",23,0.12345678901234567e+300},   {".12345678901234567e+301",23,0.12345678901234567e+301}, }; for(size_t i=0; i<sizeof(chk_dtab)/sizeof(ChkSmpDouble); ++i) {   chk_dtab[i].verify(); }; ChkSmpFloat chk_ftab[]={   {".0",2,0.0},   {".00",3,0.0},   {"1",1,1.0},   {"0.045600",8,0.0456},   {"00.045600",9,0.0456},{".045600",7,0.0456},   {"1e2",3,100.0},   {"-23.456",7,-23.456},   {"23.456e-1",9,2.3456},   {".123456789e0",12,0.123456789},   {".123456789e-1",13,0.123456789e-1},   {".123456789e-2",13,0.123456789e-2},   {".123456789e-3",13,0.123456789e-3},   {".123456789e-4",13,0.123456789e-4},   {".123456789e-5",13,0.123456789e-5},   {".123456789e-30",14,0.123456789e-30},   {".123456789e-31",14,0.123456789e-31},   {".123456789012345678e0",21,0.123456789012345678},   {".12345678901234567e-1",21,0.12345678901234567e-1},   {".12345678901234567e-2",21,0.12345678901234567e-2},   {".12345678901234567e-3",21,0.12345678901234567e-3},   {".12345678901234567e-4",21,0.12345678901234567e-4},   {".12345678901234567e-5",21,0.12345678901234567e-5},   {".12345678901234567e+1",21,0.12345678901234567e+1},   {".12345678901234567e+2",21,0.12345678901234567e+2},   {".12345678901234567e+3",21,0.12345678901234567e+3},   {".12345678901234567e+4",21,0.12345678901234567e+4},   {".12345678901234567e+5",21,0.12345678901234567e+5},   {".12345678901234567e+30",22,0.12345678901234567e+30},   {".12345678901234567e+31",22,0.12345678901234567e+31}, }; for(size_t i=0; i<sizeof(chk_ftab)/sizeof(ChkSmpFloat); ++i) {   chk_ftab[i].verify(); }; WyRet r; // check error (double) {  const char nstr[]="12.-34";  const char* cptr;  double res;  if((r=Wy::_strnum(res,&cptr,WyCSeg(nstr,sizeof(nstr)-1)))!=Wym_EBADMSG) {    WY_THROW(r);  } } // check error (float) {  const char nstr[]="12.-34";  const char* cptr;  float res;  if((r=Wy::_strnum(res,&cptr,WyCSeg(nstr,sizeof(nstr)-1)))!=Wym_EBADMSG) {    WY_THROW(r);  } }};static void t_sci(void){ struct ChkSmp {   double num;   double frac;   double p10;   void verify(void) const      {       const double ErrRate=1e-14;       double t1,t2;       try {         t1=WyMath::_scif(num,t2);         if(frac==0) {           if(std::fabs(t1)>ErrRate) {             WY_THROW( WyRet() );           }         } else {           if(std::fabs((t1-frac)/frac)>ErrRate) {             WY_THROW( WyRet() );           }         }         if(p10==0) {           if(std::fabs(t2)>ErrRate) {             WY_THROW( WyRet() );           }         } else {           if(std::fabs((t2-p10)/p10)>ErrRate) {             WY_THROW( WyRet() );           }         }       }       catch(...) {         std::cerr << "ChkSmp={" << num << "," << frac << "," << p10                    << "}  t1=" << t1 << " ,t2=" << t2 << std::endl;         throw;       };   }; } const chk_tab[]={   // num, frac, p10   {0.0,0.0,0.0},   {0.1,1.0,-1.0},   {0.01,1.0,-2.0},   {1,1.0,0.0},   {10,1.0,1.0},   {100,1.0,2.0},   {0.5,5.0,-1.0},   {5,5.0,0.0},   {50,5.0,1.0}, }; for(size_t i=0; i<sizeof(chk_tab)/sizeof(ChkSmp); ++i) {   chk_tab[i].verify(); } // // chk Math::_scif(...) conversion error limit // for(int i=0; i<65535L; ++i) {   static int rnd_sign=0;   double rnd0=::rand()/(RAND_MAX+1.0);  // rand [0,1)   double rnd1=200-(::rand()%400);  // rand  [-199,200]   double rnda=rnd0*::pow(10.0,rnd1);   ++rnd_sign;   if(rnd_sign&1) {     rnda=-rnda;   }   //std::cout << rnda << std::endl;   double a1,a2;   a1=WyMath::_scif(rnda,a2);   if(a1>0) {     // chk a1 range [1,10)     if(a1<1.0) {       WY_THROW( WyRet() );     } else if(a1>=10.0) {       WY_THROW( WyRet() );     } else {}   } else if(a1<0) {     // chk a1 range (-10,-1]     if(a1<=-10.0) {       WY_THROW( WyRet() );     } else if(a1>-1.0) {       WY_THROW( WyRet() );     } else {}   } else {     if(rnda!=0) {       WY_THROW( WyRet() );     }   }   // chk not much error of the result   {     const double ans=a1*::pow(10.0,a2);  // convert back to check error ratio     if(rnda!=0) {       double err_rate=std::abs((ans-rnda)/rnda);       if(err_rate>ErrRate_Sci) {         std::cerr << "err_rate=" << err_rate << std::endl;         WY_THROW( WyRet() );       }     } else {       if(ans!=0) {         WY_THROW( WyRet() );       }     }   } }};void ck_math(void){ t_strnum(); t_sci();};

⌨️ 快捷键说明

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