鱼C论坛

 找回密码
 立即注册
查看: 1158|回复: 6

[技术交流] 字符串计算第二版

[复制链接]
发表于 2020-1-3 02:33:22 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 bin554385863 于 2020-1-3 16:15 编辑

lnum.h

  1. #ifndef LNUM_H
  2. #define LNUM_H
  3. #include <iostream>
  4. #include <string>
  5. #include <vector>
  6. using std::istream;
  7. using std::ostream;
  8. using std::string;
  9. using std::vector;
  10. class lnum
  11. {
  12.     typedef vector<int> vecint;
  13.     struct attr
  14.     {
  15.         string str;
  16.         int sign;
  17.         vecint vec;
  18.         size_t nsize, dsize;
  19.     };
  20.     struct align
  21.     {
  22.         vecint first, second;
  23.     };
  24.    
  25. private:
  26.     attr num;
  27.     static size_t precision;
  28.     //初始化构造函数的数据
  29.     const attr InitData(const string &s);
  30.     //判断是否有效的数字字符串
  31.     const bool IsNumStr(const string &s) const;
  32.     //判断字符串元素是否全为'0'
  33.     const bool IsStrElemZero(const string &s) const;
  34.     //清除无效的0
  35.     const string ClearStrZero(const string &s) const;
  36.     //获取正负符号
  37.     const int getSign(const string &s) const;
  38.     //获取数组
  39.     const vecint Str2Vec(const string &s) const;
  40.     //获取数字字符串
  41.     const string Vec2Str(const vecint &v, int sgn, size_t dps) const;
  42.     //获取小数位数
  43.     const size_t getDpsize(const string &s) const;
  44.     //整体对齐
  45.     const align nAlign(const lnum &l) const;
  46.     //小数位对齐
  47.     const align dAlign(const lnum &l) const;
  48.     //满十进一
  49.     void Carry(vecint &v) const;
  50.     //借一
  51.     void Borrow(vecint &v) const;
  52.     //数组乘整数
  53.     lnum operator*(const int i) const;

  54. public:
  55.     lnum(const char *cstr = "0") : num(InitData(cstr)) {}
  56.     lnum(const string &s) : num(InitData(s)) {}
  57.     lnum(const lnum &l) : num(l.num) {}
  58.     void showinfo() const;
  59.     //(1)重载>
  60.     const bool operator>(const lnum &l) const;
  61.     //(2)重载==
  62.     const bool operator==(const lnum &l) const;
  63.     //(2.5)重载!=
  64.     const bool operator!=(const lnum &l) const;
  65.     //(3)重载>=
  66.     const bool operator>=(const lnum &l) const;
  67.     //(4)重载<
  68.     const bool operator<(const lnum &l) const;
  69.     //(5)重载<=
  70.     const bool operator<=(const lnum &l) const;
  71.     //(6)重载+
  72.     const lnum operator+(const lnum &l) const;
  73.     //(7)重载-,反转正负
  74.     const lnum operator-() const;
  75.     void static setprecision(const unsigned i);
  76.     friend ostream &operator<<(ostream &os, const lnum &l);
  77.     friend istream &operator>>(istream &is, lnum &l);
  78.     virtual ~lnum() {}
  79. };
  80. size_t lnum::precision = 3;
  81. #endif
复制代码


lnum.cpp

  1. #include "E:\Users\admin\Documents\VScode\Code\My Class\largenum\lnum.h"
  2. //(1)初始化构造函数的数据
  3. const lnum::attr lnum::InitData(const string &s)
  4. {
  5.     attr n = {ClearStrZero(s),
  6.               getSign(n.str),
  7.               Str2Vec(n.str),
  8.               n.vec.size(),
  9.               getDpsize(n.str)};
  10.     return n;
  11. }
  12. //(2)判断是否有效的数字字符串
  13. const bool lnum::IsNumStr(const string &s) const
  14. {
  15.     bool f = true;
  16.     string str = s;
  17.     if (str[0] == '-')
  18.     {
  19.         str.erase(0, 1);
  20.     }
  21.     if (int(str.find('.')) == -1)
  22.     {
  23.         for (char &c : str)
  24.         {
  25.             if (!isdigit(c))
  26.             {
  27.                 f = false;
  28.                 break;
  29.             }
  30.         }
  31.     }
  32.     else
  33.     {
  34.         if ((str.find('.') == 0) || (str.find('.')) == (str.size() - 1) || (s.find('.') != s.rfind('.')))
  35.         {
  36.             f = false;
  37.         }
  38.         else
  39.         {
  40.             str.erase(str.find('.'), 1);
  41.             for (char &c : str)
  42.             {
  43.                 if (!isdigit(c))
  44.                 {
  45.                     f = false;
  46.                     break;
  47.                 }
  48.             }
  49.         }
  50.     }
  51.     return f;
  52. }
  53. //(3)判断字符串元素是否全为'0'
  54. const bool lnum::IsStrElemZero(const string &s) const
  55. {
  56.     bool f = false;
  57.     string str = s;
  58.     if (str[0] == '-')
  59.     {
  60.         str.erase(0, 1);
  61.     }
  62.     if (int(s.find('.')) != -1)
  63.     {
  64.         str.erase(str.find('.'), 1);
  65.     }
  66.     if (str == string(str.size(), '0'))
  67.     {
  68.         f = true;
  69.     }
  70.     return f;
  71. }
  72. //(4)清除无效的0
  73. const string lnum::ClearStrZero(const string &s) const
  74. {
  75.     string str = "0";
  76.     if (IsNumStr(s) && (!IsStrElemZero(s)))
  77.     {
  78.         str = s;
  79.         if (str[0] == '-')
  80.         {
  81.             str.erase(0, 1);
  82.         }
  83.         size_t i = 0;
  84.         if (int(s.find('.')) == -1)
  85.         {
  86.             size_t sz = str.size();
  87.             while (i != sz)
  88.             {
  89.                 if (str[i] != '0')
  90.                 {
  91.                     break;
  92.                 }
  93.                 i++;
  94.             }
  95.             if (i == sz)
  96.             {
  97.                 str.erase(0, i - 1);
  98.             }
  99.             else
  100.             {
  101.                 str.erase(0, i);
  102.             }
  103.         }
  104.         else
  105.         {

  106.             i = 0;
  107.             while (str[i] != '.')
  108.             {
  109.                 if (str[i] != '0')
  110.                 {
  111.                     break;
  112.                 }
  113.                 i++;
  114.             }
  115.             if (i == str.find('.'))
  116.             {
  117.                 str.erase(0, i - 1);
  118.             }
  119.             else
  120.             {
  121.                 str.erase(0, i);
  122.             }
  123.             i = str.size() - 1;
  124.             while (str[i] != '.')
  125.             {
  126.                 if (str[i] != '0')
  127.                 {
  128.                     break;
  129.                 }
  130.                 i--;
  131.             }
  132.             if (i == str.find('.'))
  133.             {
  134.                 str.erase(i);
  135.             }
  136.             else if (i < str.size() - 1)
  137.             {
  138.                 str.erase(i + 1);
  139.             }
  140.         }
  141.         if (s[0] == '-')
  142.         {
  143.             str.insert(0, 1, '-');
  144.         }
  145.     }
  146.     return str;
  147. }
  148. //(5)获取正负符号
  149. const int lnum::getSign(const string &s) const
  150. {
  151.     int sgn = 0;
  152.     if (s != "0")
  153.     {
  154.         sgn = s[0] == '-' ? -1 : 1;
  155.     }
  156.     return sgn;
  157. }
  158. //(6)获取数组
  159. const lnum::vecint lnum::Str2Vec(const string &s) const
  160. {
  161.     vecint v = {0};
  162.     if (IsNumStr(s))
  163.     {
  164.         string str = s;
  165.         if (str[0] == '-')
  166.         {
  167.             str.erase(0, 1);
  168.         }
  169.         if (int(s.find('.')) != -1)
  170.         {
  171.             str.erase(str.find('.'), 1);
  172.         }
  173.         v.clear();
  174.         for (char &c : str)
  175.         {
  176.             v.push_back(c - 48);
  177.         }
  178.     }
  179.     return v;
  180. }
  181. //(7)获取数字字符串
  182. const string lnum::Vec2Str(const vecint &v, int sgn, size_t dps) const
  183. {
  184.     string str = "0";
  185.     if (sgn != 0)
  186.     {
  187.         str.clear();
  188.         for (const int &i : v)
  189.         {
  190.             str.push_back(i + 48);
  191.         }
  192.         if (dps != 0)
  193.         {
  194.             str.insert(str.size() - dps, 1, '.');
  195.         }
  196.         if (sgn == -1)
  197.         {
  198.             str.insert(0, 1, '-');
  199.         }
  200.     }
  201.     return str;
  202. }
  203. //(8)获取小数位数
  204. const size_t lnum::getDpsize(const string &s) const
  205. {
  206.     size_t dps = 0;
  207.     if (s.find('.') != -1)
  208.     {
  209.         dps = s.size() - s.find('.') - 1;
  210.     }
  211.     return dps;
  212. }
  213. //(9)整体对齐
  214. const lnum::align lnum::nAlign(const lnum &l) const
  215. {
  216.     align agn;
  217.     const vecint &tvec = num.vec, &lvec = l.num.vec;
  218.     vecint &fst = agn.first, &sec = agn.second;
  219.     const size_t &tdps = num.dsize, &ldps = l.num.dsize;
  220.     fst = tvec;
  221.     sec = lvec;
  222.     tdps > ldps ? sec.insert(sec.end(), tdps - ldps, 0) : fst.insert(fst.end(), ldps - tdps, 0);
  223.     const size_t &fsz = fst.size(), ssz = sec.size();
  224.     fsz > ssz ? sec.insert(sec.begin(), fsz - ssz, 0) : fst.insert(fst.begin(), ssz - fsz, 0);
  225.     return agn;
  226. }
  227. //(10)小数位对齐
  228. const lnum::align lnum::dAlign(const lnum &l) const
  229. {
  230.     align agn;
  231.     vecint &fst = agn.first, &sec = agn.second;
  232.     const size_t &tdps = num.dsize, &ldps = l.num.dsize;
  233.     fst = num.vec;
  234.     sec = l.num.vec;
  235.     tdps > ldps ? sec.insert(sec.end(), tdps - ldps, 0) : fst.insert(fst.end(), ldps - tdps, 0);
  236.     return agn;
  237. }
  238. //满十进一
  239. void lnum::Carry(vecint &v) const
  240. {
  241.     v.insert(v.begin(), 1, 0);
  242.     size_t sz = v.size();
  243.     for (size_t i = sz - 1; i > 0; i--)
  244.     {
  245.         int t = v[i];
  246.         v[i] = t % 10;
  247.         v[i - 1] += t / 10;
  248.     }
  249. }
  250. //借一
  251. void lnum::Borrow(vecint &v) const
  252. {
  253.     size_t s = v.size();
  254.     for (size_t i = 1; i < s; i++)
  255.     {
  256.         v[i - 1] -= 1;
  257.         v[i] += 10;
  258.     }
  259. }
  260. //数组乘整数
  261. lnum lnum::operator*(const int i) const
  262. {
  263.     lnum t = *this, r = "0";
  264.     if (num.sign != 0)
  265.     {
  266.         attr &rum = t.num;
  267.         for (int &k : rum.vec)
  268.         {
  269.             k *= i;
  270.         }
  271.         Carry(rum.vec);
  272.         r = ClearStrZero(Vec2Str(rum.vec, rum.sign, rum.dsize));
  273.     }
  274.     return r;
  275. }
  276. /***********************************************************************/
  277. //数字属性
  278. void lnum::showinfo() const
  279. {
  280.     std::cout << "正/负/零: " << num.sign << "\n"
  281.               << "原始字符: " << num.str << "\n"
  282.               << "数字元素: ";
  283.     for (const int &i : num.vec)
  284.     {
  285.         std::cout << i << " ";
  286.     }
  287.     std::cout << std::endl;
  288.     std::cout << "数字长度: " << num.nsize << "\n"
  289.               << "小数位数: " << num.dsize << std::endl;
  290. }
  291. //(1)重载>
  292. const bool lnum::operator>(const lnum &l) const
  293. {
  294.     bool f = true;
  295.     const align agn = this->nAlign(l);
  296.     const vecint &fst = agn.first,
  297.                  &sec = agn.second;
  298.     const int tsgn = num.sign, &lsgn = l.num.sign;
  299.     if (tsgn < lsgn)
  300.     {
  301.         f = false;
  302.     }
  303.     else if (tsgn == lsgn)
  304.     {
  305.         f = fst > sec;
  306.         if (tsgn < 0)
  307.         {
  308.             f = !f;
  309.         }
  310.     }
  311.     return f;
  312. }
  313. //(2)重载==
  314. const bool lnum::operator==(const lnum &l) const
  315. {
  316.     const align agn = this->nAlign(l);
  317.     const vecint &fst = agn.first,
  318.                  &sec = agn.second;
  319.     return (num.sign == l.num.sign) && (fst == sec);
  320. }
  321. //(2.5)重载!=
  322. const bool lnum::operator!=(const lnum &l) const
  323. {
  324.     return !(*this == l);
  325. }
  326. //(3)重载>=
  327. const bool lnum::operator>=(const lnum &l) const
  328. {
  329.     return (*this == l || *this > l);
  330. }
  331. //(4)重载<
  332. const bool lnum::operator<(const lnum &l) const
  333. {
  334.     return !(*this >= l);
  335. }
  336. //(5)重载<=
  337. const bool lnum::operator<=(const lnum &l) const
  338. {
  339.     return (*this < l || *this == l);
  340. }
  341. //(6)重载+
  342. const lnum lnum::operator+(const lnum &l) const
  343. {
  344.     lnum r = "0";
  345.     const int &tsgn = num.sign, &lsgn = l.num.sign;
  346.     if ((tsgn == 0 && lsgn != 0) || (tsgn != 0 && lsgn == 0))
  347.     {
  348.         r = (tsgn != 0) > (lsgn != 0) ? *this : l;
  349.     }
  350.     else if (*this != (-l))
  351.     {
  352.         int sgn = -1;
  353.         const size_t &tds = num.dsize, &lds = l.num.dsize,
  354.                      &ds = tds > lds ? tds : lds;
  355.         align agn = this->nAlign(l);
  356.         vecint &fst = agn.first, &sec = agn.second, t = fst >= sec ? fst : sec;
  357.         size_t s = fst.size();
  358.         for (size_t i = 0; i < s; i++)
  359.         {
  360.             t[i] += ((tsgn * lsgn) * ((sec <= fst ? sec : fst)[i]));
  361.         }
  362.         if ((fst < sec && tsgn < lsgn) || (sec < fst && lsgn < tsgn) || (tsgn == lsgn && tsgn == 1))
  363.         {
  364.             sgn = 1;
  365.         }
  366.         if (tsgn!=lsgn)
  367.         {
  368.             Borrow(t);
  369.         }
  370.         Carry(t);
  371.         attr &rum = r.num;
  372.         rum.str = ClearStrZero(Vec2Str(t, sgn, ds));
  373.         rum.vec = Str2Vec(rum.str);
  374.         rum.nsize = rum.vec.size();
  375.         rum.dsize = ds;
  376.         rum.sign = sgn;
  377.     }
  378.     return r;
  379. }
  380. //(7)重载-,反转正负
  381. const lnum lnum::operator-() const
  382. {
  383.     lnum r = *this;
  384.     r.num.sign = -num.sign;
  385.     r.num.str = Vec2Str(num.vec, -num.sign, num.dsize);
  386.     return r;
  387. }
  388. void lnum::setprecision(const size_t i)
  389. {
  390.     lnum::precision = i;
  391. }
  392. ostream &operator<<(ostream &os, const lnum &l)
  393. {
  394.     os << l.num.str;
  395.     return os;
  396. }
  397. istream &operator>>(istream &is, lnum &l)
  398. {
  399.     string inputstr;
  400.     (is >> inputstr).get();
  401.     l = inputstr;
  402.     return is;
  403. }
复制代码

=======================================================================
  1. #include "E:\Users\admin\Documents\VScode\Code\My Class\largenum\lnum.cpp"
  2. int main(int argc, char const *argv[])
  3. {
  4.     lnum a = "-5.000009", b = "6000";
  5.     std::cout << (a + b) << std::endl;
  6.     (a + b).showinfo();
  7.     return 0;
  8. }
复制代码

--------------------------------------------------------------------------------------------------
Microsoft Windows [版本 10.0.18363.535]
(c) 2019 Microsoft Corporation。保留所有权利。

E:\Users\admin\Documents\VScode\Code>c:\Users\admin\.vscode\extensions\ms-vscode.cpptools-0.26.2\debugAdapters\bin\WindowsDebugLauncher.exe --stdin=Microsoft-MIEngine-In-tmgi4wns.nfx --stdout=Microsoft-MIEngine-Out-sz504ytr.rqz --stderr=Microsoft-MIEngine-Error-ni2x4gi1.12t --pid=Microsoft-MIEngine-Pid-mtm4v2ay.ggn --dbgExe=D:\MinGW\bin\gdb.exe --interpreter=mi
5994.999991
正/负/零: 1
原始字符: 5994.999991
数字元素: 5 9 9 4 9 9 9 9 9 1
数字长度: 10
小数位数: 6


E:\Users\admin\Documents\VScode\Code>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-1-3 18:08:54 | 显示全部楼层
__优化代码
__添加算法
__实现精度输出

lnum.cpp

  1. #ifndef LNUM_H
  2. #define LNUM_H
  3. #include <iostream>
  4. #include <string>
  5. #include <vector>
  6. using std::istream;
  7. using std::ostream;
  8. using std::string;
  9. using std::vector;
  10. class lnum
  11. {
  12.     typedef vector<int> vecint;
  13.     struct attr
  14.     {
  15.         string str = "0";
  16.         int sign = 0;
  17.         vecint vec = {0};
  18.         size_t nsize = 1, dsize = 0;
  19.     };
  20.     struct align
  21.     {
  22.         vecint first, second;
  23.     };
  24.    
  25. private:
  26.     attr num;
  27.     static size_t precision;
  28.     //初始化构造函数的数据
  29.     const attr InitData(const string &s);
  30.     //判断是否有效的数字字符串
  31.     const bool IsNumStr(const string &s) const;
  32.     //判断字符串元素是否全为'0'
  33.     const bool IsStrElemZero(const string &s) const;
  34.     //清除无效的0
  35.     const string ClearStrZero(const string &s) const;
  36.     //获取正负符号
  37.     const int getSign(const string &s) const;
  38.     //获取数组
  39.     const vecint Str2Vec(const string &s) const;
  40.     //获取数字字符串
  41.     const string Vec2Str(const vecint &v, int sgn, size_t dps) const;
  42.     //获取小数位数
  43.     const size_t getDsize(const string &s) const;
  44.     //整体对齐
  45.     const align nAlign(const lnum &l) const;
  46.     //小数位对齐
  47.     const align dAlign(const lnum &l) const;
  48.     //满十进一
  49.     void Carry(vecint &v) const;
  50.     //借一
  51.     void Borrow(vecint &v) const;
  52.     //数组乘整数
  53.     lnum operator*(const int i) const;
  54.     //输出字符串
  55.     const string outPutStr() const;

  56. public:

  57.     lnum(const char *cstr = "0") : num(InitData(cstr)) {}
  58.     lnum(const string &s) : num(InitData(s)) {}
  59.     lnum(const lnum &l) : num(l.num) {}
  60.     void showinfo() const;
  61.     //(1)重载>
  62.     const bool operator>(const lnum &l) const;
  63.     //(2)重载==
  64.     const bool operator==(const lnum &l) const;
  65.     //(2.5)重载!=
  66.     const bool operator!=(const lnum &l) const;
  67.     //(3)重载>=
  68.     const bool operator>=(const lnum &l) const;
  69.     //(4)重载<
  70.     const bool operator<(const lnum &l) const;
  71.     //(5)重载<=
  72.     const bool operator<=(const lnum &l) const;
  73.     //(6)重载+
  74.     const lnum operator+(const lnum &l) const;
  75.     //(7)重载-,反转正负
  76.     const lnum operator-() const;
  77.     //(8)重载-
  78.     const lnum operator-(const lnum &l) const;
  79.     //(9)重载+=
  80.     const lnum &operator+=(const lnum &l);
  81.     //(10)重载++
  82.     const lnum &operator++();
  83.     //(11)重载-=
  84.     const lnum &operator-=(const lnum &l);
  85.     //(12)重载--
  86.     const lnum &operator--();
  87.     //(13)前置++
  88.     friend const lnum &operator++(lnum &l, const int i);
  89.     //(14)前置--
  90.     friend const lnum &operator--(lnum &l, const int i);
  91.     void static setprecision(const unsigned i);
  92.     friend ostream &operator<<(ostream &os, const lnum &l);
  93.     friend istream &operator>>(istream &is, lnum &l);
  94.     virtual ~lnum() {}
  95. };
  96. size_t lnum::precision = 0;
  97. #endif
复制代码


lnum.cpp

  1. #include "E:\Users\admin\Documents\VScode\Code\My Class\largenum\lnum.h"
  2. //(1)初始化构造函数的数据
  3. const lnum::attr lnum::InitData(const string &s)
  4. {
  5.     attr n = {ClearStrZero(s),
  6.               getSign(n.str),
  7.               Str2Vec(n.str),
  8.               n.vec.size(),
  9.               getDsize(n.str)};
  10.     return n;
  11. }
  12. //(2)判断是否有效的数字字符串
  13. const bool lnum::IsNumStr(const string &s) const
  14. {
  15.     bool f = true;
  16.     string str = s;
  17.     if (str[0] == '-')
  18.     {
  19.         str.erase(0, 1);
  20.     }
  21.     if (int(str.find('.')) == -1)
  22.     {
  23.         for (char &c : str)
  24.         {
  25.             if (!isdigit(c))
  26.             {
  27.                 f = false;
  28.                 break;
  29.             }
  30.         }
  31.     }
  32.     else
  33.     {
  34.         if ((str.find('.') == 0) || (str.find('.')) == (str.size() - 1) || (s.find('.') != s.rfind('.')))
  35.         {
  36.             f = false;
  37.         }
  38.         else
  39.         {
  40.             str.erase(str.find('.'), 1);
  41.             for (char &c : str)
  42.             {
  43.                 if (!isdigit(c))
  44.                 {
  45.                     f = false;
  46.                     break;
  47.                 }
  48.             }
  49.         }
  50.     }
  51.     return f;
  52. }
  53. //(3)判断字符串元素是否全为'0'
  54. const bool lnum::IsStrElemZero(const string &s) const
  55. {
  56.     bool f = false;
  57.     string str = s;
  58.     if (str[0] == '-')
  59.     {
  60.         str.erase(0, 1);
  61.     }
  62.     if (int(s.find('.')) != -1)
  63.     {
  64.         str.erase(str.find('.'), 1);
  65.     }
  66.     if (str == string(str.size(), '0'))
  67.     {
  68.         f = true;
  69.     }
  70.     return f;
  71. }
  72. //(4)清除无效的0
  73. const string lnum::ClearStrZero(const string &s) const
  74. {
  75.     string str = "0";
  76.     if (IsNumStr(s) && (!IsStrElemZero(s)))
  77.     {
  78.         str = s;
  79.         if (str[0] == '-')
  80.         {
  81.             str.erase(0, 1);
  82.         }
  83.         size_t i = 0;
  84.         if (int(s.find('.')) == -1)
  85.         {
  86.             size_t sz = str.size();
  87.             while (i != sz)
  88.             {
  89.                 if (str[i] != '0')
  90.                 {
  91.                     break;
  92.                 }
  93.                 i++;
  94.             }
  95.             if (i == sz)
  96.             {
  97.                 str.erase(0, i - 1);
  98.             }
  99.             else
  100.             {
  101.                 str.erase(0, i);
  102.             }
  103.         }
  104.         else
  105.         {

  106.             i = 0;
  107.             while (str[i] != '.')
  108.             {
  109.                 if (str[i] != '0')
  110.                 {
  111.                     break;
  112.                 }
  113.                 i++;
  114.             }
  115.             if (i == str.find('.'))
  116.             {
  117.                 str.erase(0, i - 1);
  118.             }
  119.             else
  120.             {
  121.                 str.erase(0, i);
  122.             }
  123.             i = str.size() - 1;
  124.             while (str[i] != '.')
  125.             {
  126.                 if (str[i] != '0')
  127.                 {
  128.                     break;
  129.                 }
  130.                 i--;
  131.             }
  132.             if (i == str.find('.'))
  133.             {
  134.                 str.erase(i);
  135.             }
  136.             else if (i < str.size() - 1)
  137.             {
  138.                 str.erase(i + 1);
  139.             }
  140.         }
  141.         if (s[0] == '-')
  142.         {
  143.             str.insert(0, 1, '-');
  144.         }
  145.     }
  146.     return str;
  147. }
  148. //(5)获取正负符号
  149. const int lnum::getSign(const string &s) const
  150. {
  151.     int sgn = 0;
  152.     if (s != "0")
  153.     {
  154.         sgn = s[0] == '-' ? -1 : 1;
  155.     }
  156.     return sgn;
  157. }
  158. //(6)获取数组
  159. const lnum::vecint lnum::Str2Vec(const string &s) const
  160. {
  161.     vecint v = {0};
  162.     if (IsNumStr(s))
  163.     {
  164.         string str = s;
  165.         if (str[0] == '-')
  166.         {
  167.             str.erase(0, 1);
  168.         }
  169.         if (int(s.find('.')) != -1)
  170.         {
  171.             str.erase(str.find('.'), 1);
  172.         }
  173.         v.clear();
  174.         for (char &c : str)
  175.         {
  176.             v.push_back(c - 48);
  177.         }
  178.     }
  179.     return v;
  180. }
  181. //(7)获取数字字符串
  182. const string lnum::Vec2Str(const vecint &v, int sgn, size_t dps) const
  183. {
  184.     string str = "0";
  185.     if (sgn != 0)
  186.     {
  187.         str.clear();
  188.         for (const int &i : v)
  189.         {
  190.             str.push_back(i + 48);
  191.         }
  192.         if (dps != 0)
  193.         {
  194.             str.insert(str.size() - dps, 1, '.');
  195.         }
  196.         if (sgn == -1)
  197.         {
  198.             str.insert(0, 1, '-');
  199.         }
  200.     }
  201.     return str;
  202. }
  203. //(8)获取小数位数
  204. const size_t lnum::getDsize(const string &s) const
  205. {
  206.     size_t dps = 0;
  207.     if (s.find('.') != -1)
  208.     {
  209.         dps = s.size() - s.find('.') - 1;
  210.     }
  211.     return dps;
  212. }
  213. //(9)整体对齐
  214. const lnum::align lnum::nAlign(const lnum &l) const
  215. {
  216.     align agn;
  217.     const vecint &tvec = num.vec, &lvec = l.num.vec;
  218.     vecint &fst = agn.first, &sec = agn.second;
  219.     const size_t &tdps = num.dsize, &ldps = l.num.dsize;
  220.     fst = tvec;
  221.     sec = lvec;
  222.     tdps > ldps ? sec.insert(sec.end(), tdps - ldps, 0) : fst.insert(fst.end(), ldps - tdps, 0);
  223.     const size_t &fsz = fst.size(), &ssz = sec.size();
  224.     fsz > ssz ? sec.insert(sec.begin(), fsz - ssz, 0) : fst.insert(fst.begin(), ssz - fsz, 0);
  225.     return agn;
  226. }
  227. //(10)小数位对齐
  228. const lnum::align lnum::dAlign(const lnum &l) const
  229. {
  230.     align agn;
  231.     vecint &fst = agn.first, &sec = agn.second;
  232.     const size_t &tdps = num.dsize, &ldps = l.num.dsize;
  233.     fst = num.vec;
  234.     sec = l.num.vec;
  235.     tdps > ldps ? sec.insert(sec.end(), tdps - ldps, 0) : fst.insert(fst.end(), ldps - tdps, 0);
  236.     return agn;
  237. }
  238. //满十进一
  239. void lnum::Carry(vecint &v) const
  240. {
  241.     v.insert(v.begin(), 1, 0);
  242.     size_t sz = v.size();
  243.     for (size_t i = sz - 1; i > 0; i--)
  244.     {
  245.         int t = v[i];
  246.         v[i] = t % 10;
  247.         v[i - 1] += t / 10;
  248.     }
  249. }
  250. //借一
  251. void lnum::Borrow(vecint &v) const
  252. {
  253.     size_t s = v.size();
  254.     for (size_t i = 1; i < s; i++)
  255.     {
  256.         v[i - 1] -= 1;
  257.         v[i] += 10;
  258.     }
  259. }
  260. //数组乘整数
  261. lnum lnum::operator*(const int i) const
  262. {
  263.     lnum r = "0";
  264.     if (num.sign != 0)
  265.     {
  266.         r = *this;
  267.         attr &rum = r.num;
  268.         for (int &k : rum.vec)
  269.         {
  270.             k *= i;
  271.         }
  272.         Carry(rum.vec);
  273.         r =  Vec2Str(rum.vec, rum.sign, rum.dsize);
  274.     }
  275.     return r;
  276. }
  277. //输出字符串
  278. const string lnum::outPutStr() const
  279. {
  280.     string str = num.str;
  281.     const size_t &ds = num.dsize;
  282.     if (precision < ds)
  283.     {
  284.         if (precision == 0)
  285.         {
  286.             str.erase(str.size() - ds - 1);
  287.         }
  288.         else
  289.         {
  290.             str.erase(str.size() - ds);
  291.         }
  292.     }
  293.     return str;
  294. }
  295. /***********************************************************************/
  296. //数字属性
  297. void lnum::showinfo() const
  298. {
  299.     std::cout << "正/负/零: " << num.sign << "\n"
  300.               << "原始字符: " << num.str << "\n"
  301.               << "数字元素: ";
  302.     for (const int &i : num.vec)
  303.     {
  304.         std::cout << i << " ";
  305.     }
  306.     std::cout << std::endl;
  307.     std::cout << "数字长度: " << num.nsize << "\n"
  308.               << "小数位数: " << num.dsize << std::endl;
  309. }
  310. //(1)重载>
  311. const bool lnum::operator>(const lnum &l) const
  312. {
  313.     bool f = true;
  314.     const align agn = this->nAlign(l);
  315.     const vecint &fst = agn.first,
  316.                  &sec = agn.second;
  317.     const int tsgn = num.sign, &lsgn = l.num.sign;
  318.     if (tsgn < lsgn)
  319.     {
  320.         f = false;
  321.     }
  322.     else if (tsgn == lsgn)
  323.     {
  324.         f = fst > sec;
  325.         if (tsgn < 0)
  326.         {
  327.             f = !f;
  328.         }
  329.     }
  330.     return f;
  331. }
  332. //(2)重载==
  333. const bool lnum::operator==(const lnum &l) const
  334. {
  335.     const align agn = this->nAlign(l);
  336.     const vecint &fst = agn.first,
  337.                  &sec = agn.second;
  338.     return (num.sign == l.num.sign) && (fst == sec);
  339. }
  340. //(2.5)重载!=
  341. const bool lnum::operator!=(const lnum &l) const
  342. {
  343.     return !(*this == l);
  344. }
  345. //(3)重载>=
  346. const bool lnum::operator>=(const lnum &l) const
  347. {
  348.     return (*this == l || *this > l);
  349. }
  350. //(4)重载<
  351. const bool lnum::operator<(const lnum &l) const
  352. {
  353.     return !(*this >= l);
  354. }
  355. //(5)重载<=
  356. const bool lnum::operator<=(const lnum &l) const
  357. {
  358.     return (*this < l || *this == l);
  359. }
  360. //(6)重载+
  361. const lnum lnum::operator+(const lnum &l) const
  362. {
  363.     lnum r = "0";
  364.     const int &tsgn = num.sign, &lsgn = l.num.sign;
  365.     if ((tsgn == 0 && lsgn != 0) || (tsgn != 0 && lsgn == 0))
  366.     {
  367.         r = (tsgn != 0) > (lsgn != 0) ? *this : l;
  368.     }
  369.     else if (*this != (-l))
  370.     {
  371.         int sgn = -1;
  372.         const size_t &tds = num.dsize, &lds = l.num.dsize,
  373.                      &ds = tds > lds ? tds : lds;
  374.         align agn = this->nAlign(l);
  375.         vecint &fst = agn.first, &sec = agn.second, t = fst >= sec ? fst : sec;
  376.         size_t s = fst.size();
  377.         for (size_t i = 0; i < s; i++)
  378.         {
  379.             t[i] += ((tsgn * lsgn) * ((sec <= fst ? sec : fst)[i]));
  380.         }
  381.         if ((fst < sec && tsgn < lsgn) || (sec < fst && lsgn < tsgn) || (tsgn == lsgn && tsgn == 1))
  382.         {
  383.             sgn = 1;
  384.         }
  385.         if (tsgn!=lsgn)
  386.         {
  387.             Borrow(t);
  388.         }
  389.         Carry(t);
  390.         attr &rum = r.num;
  391.         rum.str = ClearStrZero(Vec2Str(t, sgn, ds));
  392.         rum.vec = Str2Vec(rum.str);
  393.         rum.nsize = rum.vec.size();
  394.         rum.dsize = ds;
  395.         rum.sign = sgn;
  396.     }
  397.     return r;
  398. }
  399. //(7)重载-,反转正负
  400. const lnum lnum::operator-() const
  401. {
  402.     lnum r = *this;
  403.     r.num.sign = -num.sign;
  404.     r.num.str = Vec2Str(num.vec, -num.sign, num.dsize);
  405.     return r;
  406. }
  407. //(8)重载-
  408. const lnum lnum::operator-(const lnum &l) const
  409. {
  410.     lnum r;
  411.     const int &tsgn = num.sign, &lsgn = l.num.sign;
  412.     if (tsgn == 0 && lsgn != 0)
  413.     {
  414.         r = -l;
  415.     }
  416.     else if (lsgn == 0 && tsgn != 0)
  417.     {
  418.         r = *this;
  419.     }
  420.     else if (lsgn != 0 && tsgn != 0)
  421.     {
  422.         r = *this + (-l);
  423.     }
  424.     return r;
  425. }
  426. //(9)重载+=
  427. const lnum &lnum::operator+=(const lnum &l)
  428. {
  429.     *this = *this + l;
  430.     return *this;
  431. }
  432. //(10)重载++
  433. const lnum &lnum::operator++()
  434. {
  435.     return *this += "1";
  436. }
  437. //(11)重载-=
  438. const lnum &lnum::operator-=(const lnum &l)
  439. {
  440.     *this = *this - l;
  441.     return *this;
  442. }
  443. //(12)重载--
  444. const lnum &lnum::operator--()
  445. {
  446.     return *this -= "1";
  447. }
  448. //(13)前置++
  449. const lnum &operator++(lnum &l, const int i)
  450. {
  451.     return ++l;
  452. }
  453. //(14)前置--
  454. const lnum &operator--(lnum &l, const int i)
  455. {
  456.     return --l;
  457. }
  458. void lnum::setprecision(const size_t i)
  459. {
  460.     lnum::precision = i;
  461. }
  462. ostream &operator<<(ostream &os, const lnum &l)
  463. {
  464.     os << l.outPutStr();
  465.     return os;
  466. }
  467. istream &operator>>(istream &is, lnum &l)
  468. {
  469.     string inPutStr;
  470.     (is >> inPutStr).get();
  471.     l = inPutStr;
  472.     return is;
  473. }
复制代码


=====================================================================

main.cpp

  1. #include "E:\Users\admin\Documents\VScode\Code\My Class\largenum\lnum.cpp"
  2. #include <ctime>
  3. int main(int argc, char const *argv[])
  4. {
  5.     lnum::setprecision(3);
  6.     lnum a, b;
  7.     srand(time(NULL));
  8.     char m[7], n[7];
  9.     n[6] = m[6] = '\0';
  10.     int k = 0;
  11.     while (k != 10)
  12.     {
  13.         for (size_t i = 0; i < 6; i++)
  14.         {
  15.             m[i] = rand() % 9 + 48;
  16.             n[i] = rand() % 9 + 48;
  17.         }
  18.         m[rand() % 2 + 2] = '.';
  19.         n[rand() % 2 + 2] = '.';
  20.         if (k % 2 == 0)
  21.         {
  22.             m[0] = '-';
  23.         }
  24.         if (k%3 == 0)
  25.         {
  26.             n[0] = '-';
  27.         }
  28.         a = m;
  29.         b = n;
  30.         std::cout << "第" << k << "组"
  31.                   << "\n"
  32.                   << "a = " << a << "  "
  33.                   << "b = " << b << "\n--------------------------------------------------\n"
  34.                   << "a >  b: " << std::boolalpha << (a > b) << "\n"
  35.                   << "a == b: " << (a == b) << "\n"
  36.                   << "a <  b: " << (a < b) << "\n--------------------------------------------------------\n"
  37.                   << "a +  b = " << (a + b) << "\n"
  38.                   << "a -   b = " << (a - b) << "\n=======================================================\n";
  39.         k++;
  40.     }
  41.    
  42.     return 0;
  43. }
复制代码

=================================================================================
Microsoft Windows [版本 10.0.18363.535]
(c) 2019 Microsoft Corporation。保留所有权利。

E:\Users\admin\Documents\VScode\Code>c:\Users\admin\.vscode\extensions\ms-vscode.cpptools-0.26.2\debugAdapters\bin\WindowsDebugLauncher.exe --stdin=Microsoft-MIEngine-In-yrdvjqxw.52e --stdout=Microsoft-MIEngine-Out-l05gzt3v.anm --stderr=Microsoft-MIEngine-Error-cyag0fjm.qse --pid=Microsoft-MIEngine-Pid-42rglrua.ou0 --dbgExe=D:\MinGW\bin\gdb.exe --interpreter=mi
第0组
a = -3.08  b = -38.58
--------------------------------------------------      
a >  b: true
a == b: false
a <  b: false
--------------------------------------------------------
a +  b = -41.66
a -  b = 35.5
=======================================================
第1组
a = 407.56  b = 601.42
--------------------------------------------------
a >  b: false
a == b: false
a <  b: true
--------------------------------------------------------
a +  b = 1008.98
a -  b = -193.86
=======================================================
第2组
a = -6.366  b = 72.44
--------------------------------------------------
a >  b: false
a == b: false
a <  b: true
--------------------------------------------------------
a +  b = 66.074
a -  b = -78.806
=======================================================
第3组
a = 652.88  b = -1.731
--------------------------------------------------
a >  b: true
a == b: false
a <  b: false
--------------------------------------------------------
a +  b = 651.149
a -  b = 654.611
=======================================================
第4组
a = -1.467  b = 745.22
--------------------------------------------------
a >  b: false
a == b: false
a <  b: true
--------------------------------------------------------
a +  b = 743.753
a -  b = -746.687
=======================================================
第5组
a = 842.55  b = 63.016
--------------------------------------------------
a >  b: true
a == b: false
a <  b: false
--------------------------------------------------------
a +  b = 905.566
a -  b = 779.534
=======================================================
第6组
a = -46.87  b = -4.057
--------------------------------------------------
a >  b: false
a == b: false
a <  b: true
--------------------------------------------------------
a +  b = -50.927
a -  b = -42.813
=======================================================
第7组
a = 10.748  b = 752.88
--------------------------------------------------
a >  b: false
a == b: false
a <  b: true
--------------------------------------------------------
a +  b = 763.628
a -  b = -742.132
=======================================================
第8组
a = -1.506  b = 804.61
--------------------------------------------------
a >  b: false
a == b: false
a <  b: true
--------------------------------------------------------
a +  b = 803.104
a -  b = -806.116
=======================================================
第9组
a = 2.626  b = -6.542
--------------------------------------------------
a >  b: true
a == b: false
a <  b: false
--------------------------------------------------------
a +  b = -3.916
a -  b = 9.168
=======================================================


E:\Users\admin\Documents\VScode\Code>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-1-5 17:38:20 | 显示全部楼层

优化代码

本帖最后由 bin554385863 于 2020-1-5 18:06 编辑

lnum.h

  1. /*
  2. (1)原始数字字符串->清除无效的零->转换数组,提取信息(小数位数,整数位数,是否为零);
  3. (2)整体对齐->比较大小,设计加/减法;
  4. (3)小数位对齐->设计数组乘整数->设计数组乘数组->实现对象乘法;
  5. (补充)实现满十进一,退一借十;
  6. */
  7. #ifndef LNUM_H
  8. #define LNUM_H
  9. #include <iostream>
  10. #include <string>
  11. #include <vector>
  12. using std::istream;
  13. using std::ostream;
  14. using std::string;
  15. using std::vector;
  16. class lnum
  17. {
  18.     struct ndata
  19.     {
  20.         int sign;
  21.         string nstr;
  22.         vector<int> nvec;
  23.         size_t isize, dsize;
  24.     };
  25.     struct align
  26.     {
  27.         vector<int> first, second;
  28.     };
  29.    
  30. private:
  31.     static size_t pre;
  32.     ndata data;
  33.     //(0)判断是否含有小数点
  34.     const bool hasDecPoint(const string &s) const;
  35.     //(1)判断字符串是否有效
  36.     const bool isInvalidStr(const string &s) const;
  37.     //(2)判断字符串元素是否全为零
  38.     const bool isStrElemAllZero(const string &s) const;
  39.     //(3)清除无效的零
  40.     const string clearInvalidZero(const string &s) const;
  41.     //(4)转换数组
  42.     const vector<int> strToVec(const string &s) const;
  43.     //(-4)转换字符串
  44.     const string vecToStr(const vector<int> &vint, int sgn, size_t dsz) const;
  45.     //(5)提取信息
  46.     const ndata getInfo(const string &s) const;
  47.     //(6)小数位对齐
  48.     align dAlign(const lnum &l) const;
  49.     //(7)整体对齐
  50.     align wAlign(const lnum &l) const;
  51.     //(8)满十进一
  52.     void carry(vector<int> &v) const;
  53.     //(9)借一补十
  54.     void borrow(vector<int> &v) const;

  55. public:
  56.     lnum(const char *cstr = "0") : data(getInfo(cstr)){}
  57.     lnum(const string &s):data(getInfo(s)){}
  58.     void showinfo() const;
  59.     //(1)>号
  60.     const bool operator>(const lnum &l) const;
  61.     //(2)==
  62.     const bool operator==(const lnum &l) const;
  63.     //(3)>=
  64.     const bool operator>=(const lnum &l) const;
  65.     //(4)<
  66.     const bool operator<(const lnum &l) const;
  67.     //(5)<=
  68.     const bool operator<=(const lnum &l) const;
  69.     //(5)!=
  70.     const bool operator!=(const lnum &l) const;
  71.     //(6)+
  72.     const lnum operator+(const lnum &l) const;
  73.     //(7)-反转正负
  74.     const lnum operator-() const;
  75.     //(F)<<
  76.     friend ostream &operator<<(ostream &os, const lnum &l);
  77. };
  78. #endif
复制代码


lnum.cpp

  1. #include "E:\Users\admin\Documents\VScode\Code\My Class\lnum\lnum.h"
  2. //(0)判断是否含有小数点
  3. const bool lnum::hasDecPoint(const string &s) const
  4. {
  5.     return int(s.find('.')) > -1 ? true : false;
  6. }
  7. //(1)判断字符串是否有效
  8. const bool lnum::isInvalidStr(const string &s) const
  9. {
  10.     bool f = true;
  11.     if (s[0] != '-'&&!isdigit(s[0]))
  12.     {
  13.         f = false;
  14.     }
  15.     else
  16.     {
  17.         string str = s;
  18.         if (str[0] == '-')
  19.         {
  20.             str.erase(0, 1);
  21.         }
  22.         if (!hasDecPoint(str))
  23.         {
  24.             for(char c:str)
  25.             {
  26.                 if (!isdigit(c))
  27.                 {
  28.                     f = false;
  29.                     break;
  30.                 }
  31.             }
  32.         }
  33.         else
  34.         {
  35.             size_t dpinx = str.find('.');
  36.             f = (dpinx == 0) || (dpinx ==  (str.size()- 1)) || (dpinx != str.rfind('.')) ? false : true;
  37.             str.erase(dpinx, 1);
  38.             for (char c : str)
  39.             {
  40.                 if (!isdigit(c))
  41.                 {
  42.                     f = false;
  43.                     break;
  44.                 }
  45.             }
  46.         }
  47.     }
  48.     return f;
  49. }
  50. //(2)判断字符串元素是否全为零
  51. const bool lnum::isStrElemAllZero(const string &s) const
  52. {
  53.     string str = s;
  54.     str[0] == '-' ? str.erase(0, 1) : str;
  55.     hasDecPoint(str) > false ? str.erase(str.find('.'), 1) : str;
  56.     return str == string(str.size(), '0') ? true : false;
  57. }
  58. //(3)清除无效的零
  59. const string lnum::clearInvalidZero(const string &s) const
  60. {
  61.     string str = s;
  62.     if (isInvalidStr(s))
  63.     {
  64.         size_t i = 0;
  65.         if (str[0] == '-')
  66.         {
  67.             str.erase(0, 1);
  68.         }
  69.         if (!hasDecPoint(s))
  70.         {
  71.             size_t sz = str.size();
  72.             while (i != sz)
  73.             {
  74.                 if (str[i] != '0')
  75.                 {
  76.                     break;
  77.                 }
  78.                 i++;
  79.             }
  80.             if (i == sz)
  81.             {
  82.                 str.erase(0, i - 1);
  83.             }
  84.             else if (i > 0)
  85.             {
  86.                 str.erase(0, i);
  87.             }
  88.         }
  89.         else
  90.         {
  91.             i = 0;
  92.             while (str[i] != '.')
  93.             {
  94.                 if (str[i] != '0')
  95.                 {
  96.                     break;
  97.                 }
  98.                 i++;
  99.             }
  100.             if (i == str.find('.'))
  101.             {
  102.                 str.erase(0, i - 1);
  103.             }
  104.             else if (i > 0)
  105.             {
  106.                 str.erase(0, i);
  107.             }
  108.             i = str.size() - 1;
  109.             while (str[i] != '.')
  110.             {
  111.                 if (str[i] != '0')
  112.                 {
  113.                     break;
  114.                 }
  115.                 i--;
  116.             }
  117.             if (i == str.find('.'))
  118.             {
  119.                 str.erase(i);
  120.             }
  121.             else if (i < str.size() - 1)
  122.             {
  123.                 str.erase(i + 1);
  124.             }
  125.         }
  126.         if (s[0] == '-' && str != "0")
  127.         {
  128.             str.insert(0, 1, '-');
  129.         }
  130.     }
  131.     return str;
  132. }
  133. //(4)转换数组
  134. const vector<int> lnum::strToVec(const string &s) const
  135. {
  136.     vector<int> vint;
  137.     string str = s;
  138.     str[0] == '-' ? str.erase(0, 1) : str;
  139.     hasDecPoint(str) > false ? str.erase(str.find('.'), 1) : str;
  140.     for (char c : str)
  141.     {
  142.         vint.push_back(c - 48);
  143.     }
  144.     return vint;
  145. }
  146. //(-4)转换字符串
  147. const string lnum::vecToStr(const vector<int> &vint, int sgn, size_t dsz) const
  148. {
  149.     string str;
  150.     for (int i : vint)
  151.     {
  152.         str.push_back(i + 48);
  153.     }
  154.     if (str != "0")
  155.     {
  156.         dsz == 0 ? str : str.insert(str.size() - dsz, 1, '.');
  157.         sgn == -1 ? str.insert(0, 1, '-') : str;
  158.     }
  159.     return str;
  160. }
  161. //(5)提取信息
  162. const lnum::ndata lnum::getInfo(const string &s) const
  163. {
  164.     ndata ndt = {0, "0", {0}, 1, 0};
  165.     if (isInvalidStr(s))
  166.     {
  167.         ndt.nstr = clearInvalidZero(s);
  168.         ndt.sign = ndt.nstr != "0" ? (ndt.nstr[0] == '-' ? -1 : 1) : 0;
  169.         ndt.dsize = hasDecPoint(ndt.nstr) || false ? ndt.nstr.size() - ndt.nstr.find('.') - 1 : 0;
  170.         ndt.nvec = strToVec(ndt.nstr);
  171.         ndt.isize = ndt.nvec.size() - ndt.dsize;
  172.     }
  173.     return ndt;
  174. }
  175. //(6)小数位对齐
  176. lnum::align lnum::dAlign(const lnum &l) const
  177. {
  178.     align agn;
  179.     vector<int> &f = agn.first, &s = agn.second;
  180.     f = data.nvec;
  181.     s = l.data.nvec;
  182.     const size_t &fds = data.dsize, &sds = l.data.dsize;
  183.     fds > sds ? s.insert(s.end(), fds - sds, 0) : f.insert(f.end(), sds - fds, 0);
  184.     return agn;
  185. }
  186. //(7)整体对齐
  187. lnum::align lnum::wAlign(const lnum &l) const
  188. {
  189.     align &&agn = this->dAlign(l);
  190.     vector<int> &f = agn.first, &s = agn.second;
  191.     const size_t &fws = data.isize, &sws = l.data.isize;
  192.     fws > sws ? s.insert(s.begin(), fws - sws, 0) : f.insert(f.begin(), sws - fws, 0);
  193.     return agn;
  194. }
  195. //(8)满十进一
  196. void lnum::carry(vector<int> &v) const
  197. {
  198.     v.insert(v.begin(), 1, 0);
  199.     const size_t s = v.size();
  200.     for (size_t i = s - 1; i != 0; i--)
  201.     {
  202.         int t = v[i];
  203.         v[i] = t % 10;
  204.         v[i - 1] += t / 10;
  205.     }
  206.     if (v[0] == 0)
  207.     {
  208.         v.erase(v.begin(), v.begin() + 1);
  209.     }
  210. }
  211. //(9)借一补十
  212. void lnum::borrow(vector<int> &v) const
  213. {
  214.     const size_t s = v.size();
  215.     for (size_t i = 1; i < s; i++)
  216.     {
  217.         v[i - 1] -= 1;
  218.         v[i] += 10;
  219.     }
  220. }
  221. //==========================================================================
  222. //(0)显示信息
  223. void lnum::showinfo() const
  224. {
  225.     std::cout << "正/负/零: " << data.sign << "\n"
  226.               << "原始数字: " << data.nstr << "\n"
  227.               << "数组元素: ";
  228.     for (int i : data.nvec)
  229.     {
  230.         std::cout << i << " ";
  231.     }
  232.     std::cout << std::endl;
  233.     std::cout << "整数位数: " << data.isize << "\n"
  234.               << "小数位数: " << data.dsize << std::endl;
  235. }
  236. //(1)>号
  237. const bool lnum::operator>(const lnum &l) const
  238. {
  239.     bool f = true;
  240.     const int &tsgn = data.sign, &lsgn = l.data.sign;
  241.     if (tsgn < lsgn)
  242.     {
  243.         f = false;
  244.     }
  245.     else if (tsgn == lsgn)
  246.     {
  247.         const align &agn = this->wAlign(l);
  248.         f = agn.first > agn.second;
  249.         if (tsgn == -1)
  250.         {
  251.             f = !f;
  252.         }
  253.     }
  254.     return f;
  255. }
  256. //(2)==
  257. const bool lnum::operator==(const lnum &l) const
  258. {
  259.     return (data.sign == l.data.sign) && (data.nvec == l.data.nvec);
  260. }
  261. //(3)>=
  262. const bool lnum::operator>=(const lnum &l) const
  263. {
  264.     return (*this > l) || (*this == l);
  265. }
  266. //(4)<
  267. const bool lnum::operator<(const lnum &l) const
  268. {
  269.     return !(*this >= l);
  270. }
  271. //(5)<=
  272. const bool lnum::operator<=(const lnum &l) const
  273. {
  274.     return (*this < l) || (*this == l);
  275. }
  276. //(5.5)!=
  277. const bool lnum::operator!=(const lnum &l) const
  278. {
  279.     return !(*this == l);
  280. }
  281. //(6)+
  282. const lnum lnum::operator+(const lnum &l) const
  283. {
  284.     lnum r;
  285.     if (*this != (-l))
  286.     {
  287.         align agn = this->wAlign(l);
  288.         vector<int> &fst = agn.first,
  289.                     &sec = agn.second,
  290.                     &greater = fst >= sec ? fst : sec,
  291.                     &less = sec <= fst ? sec : fst;
  292.         const int &tsgn = data.sign,
  293.                   &lsgn = l.data.sign;
  294.         const size_t &sz = fst.size();
  295.         for (size_t i = 0; i < sz; i++)
  296.         {
  297.             greater[i] += (lsgn * tsgn) * less[i];
  298.         }
  299.         int sgn = 1;
  300.         if (tsgn == lsgn)
  301.         {
  302.             sgn = (tsgn == 0) > (tsgn == -1) ? 0 : -1;
  303.         }
  304.         else if (tsgn != lsgn)
  305.         {
  306.             sgn = ((greater == fst && tsgn < lsgn) || (less == fst && tsgn > lsgn)) || false ? -1 : sgn;
  307.         }
  308.         if (tsgn * lsgn == -1)
  309.         {
  310.             borrow(greater);
  311.         }
  312.         carry(greater);
  313.         size_t dsz = data.dsize >= l.data.dsize ? data.dsize : l.data.dsize;
  314.         string str = vecToStr(greater, sgn, dsz);
  315.         r = str;
  316.     }
  317.     return r;
  318. }

  319. //(7)-反转正负
  320. const lnum lnum::operator-() const
  321. {
  322.     lnum r = *this;
  323.     if (data.sign != 0)
  324.     {
  325.         r.data.sign = -data.sign;
  326.         r.data.nstr = vecToStr(data.nvec, -data.sign, data.dsize);
  327.     }
  328.     return r;
  329. }
  330. //(F)<<
  331. ostream &operator<<(ostream &os, const lnum &l)
  332. {
  333.     os << l.data.nstr;
  334.     return os;
  335. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-1-5 20:08:33 | 显示全部楼层
本帖最后由 bin554385863 于 2020-1-5 20:23 编辑

继续优化

lnum.h

  1. /*
  2. (1)原始数字字符串->清除无效的零->转换数组,提取信息(小数位数,整数位数,是否为零);
  3. (2)整体对齐->比较大小,设计加/减法;
  4. (3)小数位对齐->设计数组乘整数->设计数组乘数组->实现对象乘法;
  5. (补充)实现满十进一,退一借十;
  6. */
  7. #ifndef LNUM_H
  8. #define LNUM_H
  9. #include <iostream>
  10. #include <string>
  11. #include <vector>
  12. using std::istream;
  13. using std::ostream;
  14. using std::string;
  15. using std::vector;
  16. class lnum
  17. {
  18.     struct ndata
  19.     {
  20.         int sign;
  21.         string nstr;
  22.         vector<int> nvec;
  23.         size_t isize, dsize;
  24.     };
  25.     struct align
  26.     {
  27.         vector<int> first, second;
  28.     };
  29.    
  30. private:
  31.     static size_t pre;
  32.     ndata data;
  33.     //(0)判断是否含有小数点
  34.     const bool hasDecPoint(const string &s) const;
  35.     //(1)判断字符串是否有效
  36.     const bool isInvalidStr(const string &s) const;
  37.     //(2)判断字符串元素是否全为零
  38.     const bool isStrElemAllZero(const string &s) const;
  39.     //(3)清除无效的零
  40.     const string clearInvalidZero(const string &s) const;
  41.     //(4)转换数组
  42.     const vector<int> strToVec(const string &s) const;
  43.     //(-4)转换字符串
  44.     const string vecToStr(const vector<int> &vint, int sgn, size_t dsz) const;
  45.     //(5)提取信息
  46.     const ndata getInfo(const string &s) const;
  47.     //(6)小数位对齐
  48.     align dAlign(const lnum &l) const;
  49.     //(7)整体对齐
  50.     align wAlign(const lnum &l) const;
  51.     //(8)满十进一
  52.     void carry(vector<int> &v) const;
  53.     //(9)借一补十
  54.     void borrow(vector<int> &v) const;
  55.     //(10)截断输出
  56.     const string outPut() const;

  57. public:
  58.     lnum(const char *cstr = "0") : data(getInfo(cstr)){}
  59.     lnum(const string &s):data(getInfo(s)){}
  60.     void showinfo() const;
  61.     static void setprecision(const size_t p);
  62.     //(1)>号
  63.     const bool operator>(const lnum &l) const;
  64.     //(2)==
  65.     const bool operator==(const lnum &l) const;
  66.     //(3)>=
  67.     const bool operator>=(const lnum &l) const;
  68.     //(4)<
  69.     const bool operator<(const lnum &l) const;
  70.     //(5)<=
  71.     const bool operator<=(const lnum &l) const;
  72.     //(5)!=
  73.     const bool operator!=(const lnum &l) const;
  74.     //(6)+
  75.     const lnum operator+(const lnum &l) const;
  76.     //(7)-反转正负
  77.     const lnum operator-() const;
  78.     //(F)<<
  79.     friend ostream &operator<<(ostream &os, const lnum &l);
  80.     //(F)>>
  81.     friend istream &operator>>(istream &is, lnum &l);
  82. };
  83. size_t lnum::pre = 6;
  84. #endif
复制代码


lnum.cpp

  1. #include "E:\Users\admin\Documents\VScode\Code\My Class\lnum\lnum.h"
  2. //(0)判断是否含有小数点
  3. const bool lnum::hasDecPoint(const string &s) const
  4. {
  5.     return int(s.find('.')) > -1 ? true : false;
  6. }
  7. //(1)判断字符串是否有效
  8. const bool lnum::isInvalidStr(const string &s) const
  9. {
  10.     bool f = true;
  11.     string str = s;
  12.     if (str[0] == '-')
  13.     {
  14.         str.erase(0, 1);
  15.     }
  16.     if (!hasDecPoint(str))
  17.     {
  18.         for (char c : str)
  19.         {
  20.             if (!isdigit(c))
  21.             {
  22.                 f = false;
  23.                 break;
  24.             }
  25.         }
  26.     }
  27.     else
  28.     {
  29.         size_t dpinx = str.find('.');
  30.         f = (dpinx == 0) || (dpinx == (str.size() - 1)) || (dpinx != str.rfind('.')) ? false : true;
  31.         str.erase(dpinx, 1);
  32.         for (char c : str)
  33.         {
  34.             if (!isdigit(c))
  35.             {
  36.                 f = false;
  37.                 break;
  38.             }
  39.         }
  40.     }
  41.     return f;
  42. }
  43. //(2)判断字符串元素是否全为零
  44. const bool lnum::isStrElemAllZero(const string &s) const
  45. {
  46.     string str = s;
  47.     str[0] == '-' ? str.erase(0, 1) : str;
  48.     hasDecPoint(str) || false ? str.erase(str.find('.'), 1) : str;
  49.     return str == string(str.size(), '0') ? true : false;
  50. }
  51. //(3)清除无效的零
  52. const string lnum::clearInvalidZero(const string &s) const
  53. {
  54.     string str = s;
  55.     if (isInvalidStr(s))
  56.     {
  57.         size_t i = 0;
  58.         if (str[0] == '-')
  59.         {
  60.             str.erase(0, 1);
  61.         }
  62.         if (!hasDecPoint(s))
  63.         {
  64.             size_t sz = str.size();
  65.             while (i != sz)
  66.             {
  67.                 if (str[i] != '0')
  68.                 {
  69.                     break;
  70.                 }
  71.                 i++;
  72.             }
  73.             if (i == sz)
  74.             {
  75.                 str.erase(0, i - 1);
  76.             }
  77.             else if (i > 0)
  78.             {
  79.                 str.erase(0, i);
  80.             }
  81.         }
  82.         else
  83.         {
  84.             i = 0;
  85.             while (str[i] != '.')
  86.             {
  87.                 if (str[i] != '0')
  88.                 {
  89.                     break;
  90.                 }
  91.                 i++;
  92.             }
  93.             if (i == str.find('.'))
  94.             {
  95.                 str.erase(0, i - 1);
  96.             }
  97.             else if (i > 0)
  98.             {
  99.                 str.erase(0, i);
  100.             }
  101.             i = str.size() - 1;
  102.             while (str[i] != '.')
  103.             {
  104.                 if (str[i] != '0')
  105.                 {
  106.                     break;
  107.                 }
  108.                 i--;
  109.             }
  110.             if (i == str.find('.'))
  111.             {
  112.                 str.erase(i);
  113.             }
  114.             else if (i < str.size() - 1)
  115.             {
  116.                 str.erase(i + 1);
  117.             }
  118.         }
  119.         if (s[0] == '-' && str != "0")
  120.         {
  121.             str.insert(0, 1, '-');
  122.         }
  123.     }
  124.     return str;
  125. }
  126. //(4)转换数组
  127. const vector<int> lnum::strToVec(const string &s) const
  128. {
  129.     vector<int> vint;
  130.     string str = s;
  131.     str[0] == '-' ? str.erase(0, 1) : str;
  132.     hasDecPoint(str) > false ? str.erase(str.find('.'), 1) : str;
  133.     for (char c : str)
  134.     {
  135.         vint.push_back(c - 48);
  136.     }
  137.     return vint;
  138. }
  139. //(-4)转换字符串
  140. const string lnum::vecToStr(const vector<int> &vint, int sgn, size_t dsz) const
  141. {
  142.     string str;
  143.     for (int i : vint)
  144.     {
  145.         str.push_back(i + 48);
  146.     }
  147.     if (str != "0")
  148.     {
  149.         dsz == 0 ? str : str.insert(str.size() - dsz, 1, '.');
  150.         sgn == -1 ? str.insert(0, 1, '-') : str;
  151.     }
  152.     return str;
  153. }
  154. //(5)提取信息
  155. const lnum::ndata lnum::getInfo(const string &s) const
  156. {
  157.     ndata ndt = {0, "0", {0}, 1, 0};
  158.     if (isInvalidStr(s))
  159.     {
  160.         ndt.nstr = clearInvalidZero(s);
  161.         ndt.sign = ndt.nstr != "0" ? (ndt.nstr[0] == '-' ? -1 : 1) : 0;
  162.         ndt.dsize = hasDecPoint(ndt.nstr) || false ? ndt.nstr.size() - ndt.nstr.find('.') - 1 : 0;
  163.         ndt.nvec = strToVec(ndt.nstr);
  164.         ndt.isize = ndt.nvec.size() - ndt.dsize;
  165.     }
  166.     return ndt;
  167. }
  168. //(6)小数位对齐
  169. lnum::align lnum::dAlign(const lnum &l) const
  170. {
  171.     align agn;
  172.     vector<int> &f = agn.first, &s = agn.second;
  173.     f = data.nvec;
  174.     s = l.data.nvec;
  175.     const size_t &fds = data.dsize, &sds = l.data.dsize;
  176.     fds > sds ? s.insert(s.end(), fds - sds, 0) : f.insert(f.end(), sds - fds, 0);
  177.     return agn;
  178. }
  179. //(7)整体对齐
  180. lnum::align lnum::wAlign(const lnum &l) const
  181. {
  182.     align &&agn = this->dAlign(l);
  183.     vector<int> &f = agn.first, &s = agn.second;
  184.     const size_t &fws = data.isize, &sws = l.data.isize;
  185.     fws > sws ? s.insert(s.begin(), fws - sws, 0) : f.insert(f.begin(), sws - fws, 0);
  186.     return agn;
  187. }
  188. //(8)满十进一
  189. void lnum::carry(vector<int> &v) const
  190. {
  191.     v.insert(v.begin(), 1, 0);
  192.     const size_t s = v.size();
  193.     for (size_t i = s - 1; i != 0; i--)
  194.     {
  195.         int t = v[i];
  196.         v[i] = t % 10;
  197.         v[i - 1] += t / 10;
  198.     }
  199.     if (v[0] == 0)
  200.     {
  201.         v.erase(v.begin(), v.begin() + 1);
  202.     }
  203. }
  204. //(9)借一补十
  205. void lnum::borrow(vector<int> &v) const
  206. {
  207.     const size_t s = v.size();
  208.     for (size_t i = 1; i < s; i++)
  209.     {
  210.         v[i - 1] -= 1;
  211.         v[i] += 10;
  212.     }
  213. }
  214. //(10)截断输出
  215. const string lnum::outPut() const
  216. {
  217.     const size_t &tds = data.dsize;
  218.     string str = data.nstr;
  219.     if (pre == 0)
  220.     {
  221.         if(tds != 0)
  222.         {
  223.             str.erase(str.find('.'));
  224.         }
  225.     }
  226.     else
  227.     {
  228.         if (tds > pre)
  229.         {
  230.             str.erase(str.size() - (tds - pre));
  231.         }
  232.     }
  233.     return str;
  234. }
  235. //==========================================================================
  236. //(0)显示信息
  237. void lnum::showinfo() const
  238. {
  239.     std::cout << "正/负/零: " << data.sign << "\n"
  240.               << "原始数字: " << data.nstr << "\n"
  241.               << "数组元素: ";
  242.     for (int i : data.nvec)
  243.     {
  244.         std::cout << i << " ";
  245.     }
  246.     std::cout << std::endl;
  247.     std::cout << "整数位数: " << data.isize << "\n"
  248.               << "小数位数: " << data.dsize << std::endl;
  249. }
  250. void lnum::setprecision(const size_t p)
  251. {
  252.     pre = p;
  253. }
  254. //(1)>号
  255. const bool lnum::operator>(const lnum &l) const
  256. {
  257.     bool f = true;
  258.     const int &tsgn = data.sign, &lsgn = l.data.sign;
  259.     if (tsgn < lsgn)
  260.     {
  261.         f = false;
  262.     }
  263.     else if (tsgn == lsgn)
  264.     {
  265.         const align &agn = this->wAlign(l);
  266.         f = agn.first > agn.second;
  267.         if (tsgn == -1)
  268.         {
  269.             f = !f;
  270.         }
  271.     }
  272.     return f;
  273. }
  274. //(2)==
  275. const bool lnum::operator==(const lnum &l) const
  276. {
  277.     return (data.sign == l.data.sign) && (data.nvec == l.data.nvec);
  278. }
  279. //(3)>=
  280. const bool lnum::operator>=(const lnum &l) const
  281. {
  282.     return (*this > l) || (*this == l);
  283. }
  284. //(4)<
  285. const bool lnum::operator<(const lnum &l) const
  286. {
  287.     return !(*this >= l);
  288. }
  289. //(5)<=
  290. const bool lnum::operator<=(const lnum &l) const
  291. {
  292.     return (*this < l) || (*this == l);
  293. }
  294. //(5.5)!=
  295. const bool lnum::operator!=(const lnum &l) const
  296. {
  297.     return !(*this == l);
  298. }
  299. //(6)+
  300. const lnum lnum::operator+(const lnum &l) const
  301. {
  302.     lnum r;
  303.     if (*this != (-l))
  304.     {
  305.         align agn = this->wAlign(l);
  306.         vector<int> &fst = agn.first,
  307.                     &sec = agn.second,
  308.                     &greater = fst >= sec ? fst : sec,
  309.                     &less = sec <= fst ? sec : fst;
  310.         const int &tsgn = data.sign,
  311.                   &lsgn = l.data.sign;
  312.         const size_t &sz = fst.size();
  313.         for (size_t i = 0; i < sz; i++)
  314.         {
  315.             greater[i] += (lsgn * tsgn) * less[i];
  316.         }
  317.         int sgn = 1;
  318.         if (tsgn == lsgn)
  319.         {
  320.             sgn = tsgn;
  321.         }
  322.         else if (tsgn != lsgn)
  323.         {
  324.             sgn = ((greater == fst && tsgn < lsgn) || (less == fst && tsgn > lsgn)) || false ? -1 : sgn;
  325.         }
  326.         if (tsgn * lsgn == -1)
  327.         {
  328.             borrow(greater);
  329.         }
  330.         carry(greater);
  331.         size_t dsz = data.dsize >= l.data.dsize ? data.dsize : l.data.dsize;
  332.         //string str = vecToStr(greater, sgn, dsz);
  333.         r = vecToStr(greater, sgn, dsz);
  334.     }
  335.     return r;
  336. }

  337. //(7)-反转正负
  338. const lnum lnum::operator-() const
  339. {
  340.     lnum r = *this;
  341.     if (data.sign != 0)
  342.     {
  343.         r.data.sign = -data.sign;
  344.         r.data.nstr = vecToStr(data.nvec, -data.sign, data.dsize);
  345.     }
  346.     return r;
  347. }
  348. //(F)<<
  349. ostream &operator<<(ostream &os, const lnum &l)
  350. {
  351.     os << l.outPut();
  352.     return os;
  353. }
  354. //(F)>>
  355. istream &operator>>(istream &is, lnum &l)
  356. {
  357.     string str;
  358.     (std::cin >> str).get();
  359.     l = str;
  360.     return is;
  361. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-1-5 20:25:49 | 显示全部楼层
添加减法
const lnum operator-(const lnum &l) const;

  1. const lnum lnum::operator-(const lnum &l) const
  2. {
  3.     return *this + (-l);
  4. }
复制代码


test.cpp

  1. #include "E:\Users\admin\Documents\VScode\Code\My Class\lnum\lnum.cpp"
  2. #include <ctime>
  3. #include <cmath>
  4. int main(int argc, char const *argv[])
  5. {
  6.     lnum a = "1", b;
  7.     while ((a + b) != "0")
  8.     {
  9.         std::cin >> a >> b;
  10.         std::cout << "a - b = " << (a - b) << "\n"
  11.                   << "a + b = " << (a + b) << "\n==========================\n";
  12.     }
  13.     return 0;
  14. }
复制代码

-------------------------------------------------------------------
Microsoft Windows [版本 10.0.18363.535]
(c) 2019 Microsoft Corporation。保留所有权利。

E:\Users\admin\Documents\VScode\Code>c:\Users\admin\.vscode\extensions\ms-vscode.cpptools-0.26.2\debugAdapters\bin\WindowsDebugLauncher.exe --stdin=Microsoft-MIEngine-In-x4qpcw2n.sc2 --stdout=Microsoft-MIEngine-Out-pmiyg52x.pko --stderr=Microsoft-MIEngine-Error-ycnrwdt4.obr --pid=Microsoft-MIEngine-Pid-5gacmwbw.dbc --dbgExe=D:\MinGW\bin\gdb.exe --interpreter=mi
123
654
a - b = -531
a + b = 777
==========================
999
999
a - b = 0
a + b = 1998
==========================
987654321
123456789
a - b = 864197532
a + b = 1111111110
==========================
-99
999
a - b = -1098
a + b = 900
==========================
999
-99
a - b = 1098
a + b = 900
==========================
-5555
-9999
a - b = 4444
a + b = -15554
==========================
2
0.123654
a - b = 1.876346
a + b = 2.123654
==========================
0.123456789
0.000000005
a - b = 0.123456
a + b = 0.123456
==========================
0.0006
0.0005
a - b = 0.0001
a + b = 0.0011
==========================
-0.005
0.00004
a - b = -0.00504
a + b = -0.00496
==========================
1
-0.00005
a - b = 1.00005
a + b = 0.99995
==========================
-99999
-0.0006
a - b = -99998.9994
a + b = -99999.0006
==========================
-987
987
a - b = -1974
a + b = 0
==========================


E:\Users\admin\Documents\VScode\Code>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-1-5 23:00:24 | 显示全部楼层
bin554385863 发表于 2020-1-5 20:25
添加减法
const lnum operator-(const lnum &l) const;

添加
+=
-=
++
--
  1. //(8)+=
  2.     const lnum &operator+=(const lnum &l);
  3.     //(9)++
  4.     const lnum &operator++(const int i);
  5.     //(10)-=
  6.     const lnum &operator-=(const lnum &l);
  7.     //(11)--
  8.     const lnum &operator--(const int i);
复制代码


  1. //(8)+=
  2. const lnum &lnum::operator+=(const lnum &l)
  3. {
  4.     return *this = *this + l;
  5. }
  6. //(9)++
  7. const lnum &lnum::operator++(const int i)
  8. {
  9.     return *this = *this + "1";
  10. }
  11. //(10)-=
  12. const lnum &lnum::operator-=(const lnum &l)
  13. {
  14.     return *this = *this + (-l);
  15. }
  16. //(11)--
  17. const lnum &lnum::operator--(const int i)
  18. {
  19.     return *this = *this + "-1";
  20. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-1-6 03:21:05 | 显示全部楼层
本帖最后由 bin554385863 于 2020-1-6 04:30 编辑

已经实现
数字字符串加减乘三种运算和五种比较运算,


lnum.cpp

  1. /*
  2. (1)原始数字字符串->清除无效的零->转换数组,提取信息(小数位数,整数位数,是否为零);
  3. (2)整体对齐->比较大小,设计加/减法;
  4. (3)小数位对齐->设计数组乘整数->设计数组乘数组->实现对象乘法;
  5. (补充)实现满十进一,退一借十;
  6. */
  7. #ifndef LNUM_H
  8. #define LNUM_H
  9. #include <iostream>
  10. #include <string>
  11. #include <vector>
  12. using std::istream;
  13. using std::ostream;
  14. using std::string;
  15. using std::vector;
  16. class lnum
  17. {
  18.     struct ndata
  19.     {
  20.         int sign;
  21.         string nstr;
  22.         vector<int> nvec;
  23.         size_t isize, dsize;
  24.     };
  25.     struct align
  26.     {
  27.         vector<int> first, second;
  28.     };
  29.    
  30. private:
  31.     static size_t pre;
  32.     ndata data;
  33.     //(0)判断是否含有小数点
  34.     const bool hasDecPoint(const string &s) const;
  35.     //(1)判断字符串是否有效
  36.     const bool isInvalidStr(const string &s) const;
  37.     //(2)判断字符串元素是否全为零
  38.     const bool isStrElemAllZero(const string &s) const;
  39.     //(3)清除无效的零
  40.     const string clearInvalidZero(const string &s) const;
  41.     //(4)转换数组
  42.     const vector<int> strToVec(const string &s) const;
  43.     //(-4)转换字符串
  44.     const string vecToStr(const vector<int> &vint, int sgn, size_t dsz) const;
  45.     //(5)提取信息
  46.     const ndata getInfo(const string &s) const;
  47.     //(6)小数位对齐
  48.     align dAlign(const lnum &l) const;
  49.     //(7)整体对齐
  50.     align wAlign(const lnum &l) const;
  51.     //(8)满十进一
  52.     void carry(vector<int> &v) const;
  53.     //(9)借一补十
  54.     void borrow(vector<int> &v) const;
  55.     //(10)输出设置
  56.     const string setPrint() const;
  57.     //(11)lnum*n
  58.     const lnum operator*(const int &n) const;

  59. public:
  60.     lnum(const char *cstr = "0") : data(getInfo(cstr))
  61.     {
  62.     }
  63.     lnum(const string &s):data(getInfo(s)){}
  64.     void showinfo() const;
  65.     static void setprecision(const size_t p);
  66.     //(1)>号
  67.     const bool operator>(const lnum &l) const;
  68.     //(2)==
  69.     const bool operator==(const lnum &l) const;
  70.     //(3)>=
  71.     const bool operator>=(const lnum &l) const;
  72.     //(4)<
  73.     const bool operator<(const lnum &l) const;
  74.     //(5)<=
  75.     const bool operator<=(const lnum &l) const;
  76.     //(5)!=
  77.     const bool operator!=(const lnum &l) const;
  78.     //(6)+
  79.     const lnum operator+(const lnum &l) const;
  80.     //(7)-反转正负
  81.     const lnum operator-() const;
  82.     //(7.5)-
  83.     const lnum operator-(const lnum &l) const;
  84.     //(8)+=
  85.     const lnum &operator+=(const lnum &l);
  86.     //(9)++
  87.     const lnum &operator++(const int i);
  88.     //(10)-=
  89.     const lnum &operator-=(const lnum &l);
  90.     //(11)--
  91.     const lnum &operator--(const int i);
  92.     //(12)lnum*lnum
  93.     const lnum operator*(const lnum &l) const;
  94.     //(F)<<
  95.     friend ostream &operator<<(ostream &os, const lnum &l);
  96.     //(F)>>
  97.     friend istream &operator>>(istream &is, lnum &l);
  98. };
  99. size_t lnum::pre = 6;
  100. #endif
复制代码


====================================================
lnum.cpp

  1. #include "E:\Users\admin\Documents\VScode\Code\My Class\lnum\lnum.h"
  2. //(0)判断是否含有小数点
  3. const bool lnum::hasDecPoint(const string &s) const
  4. {
  5.     return int(s.find('.')) > -1 ? true : false;
  6. }
  7. //(1)判断字符串是否有效
  8. const bool lnum::isInvalidStr(const string &s) const
  9. {
  10.     bool f = true;
  11.     string str = s;
  12.     if (str[0] == '-')
  13.     {
  14.         str.erase(0, 1);
  15.     }
  16.     if (!hasDecPoint(str))
  17.     {
  18.         for (char c : str)
  19.         {
  20.             if (!isdigit(c))
  21.             {
  22.                 f = false;
  23.                 break;
  24.             }
  25.         }
  26.     }
  27.     else
  28.     {
  29.         size_t dpinx = str.find('.');
  30.         f = (dpinx == 0) || (dpinx == (str.size() - 1)) || (dpinx != str.rfind('.')) ? false : true;
  31.         str.erase(dpinx, 1);
  32.         for (char c : str)
  33.         {
  34.             if (!isdigit(c))
  35.             {
  36.                 f = false;
  37.                 break;
  38.             }
  39.         }
  40.     }
  41.     return f;
  42. }
  43. //(2)判断字符串元素是否全为零
  44. const bool lnum::isStrElemAllZero(const string &s) const
  45. {
  46.     string str = s;
  47.     str[0] == '-' ? str.erase(0, 1) : str;
  48.     hasDecPoint(str) || false ? str.erase(str.find('.'), 1) : str;
  49.     return str == string(str.size(), '0') ? true : false;
  50. }
  51. //(3)清除无效的零
  52. const string lnum::clearInvalidZero(const string &s) const
  53. {
  54.     string str = s;
  55.     if (isInvalidStr(s))
  56.     {
  57.         size_t i = 0;
  58.         if (str[0] == '-')
  59.         {
  60.             str.erase(0, 1);
  61.         }
  62.         if (!hasDecPoint(s))
  63.         {
  64.             size_t sz = str.size();
  65.             while (i != sz)
  66.             {
  67.                 if (str[i] != '0')
  68.                 {
  69.                     break;
  70.                 }
  71.                 i++;
  72.             }
  73.             if (i == sz)
  74.             {
  75.                 str.erase(0, i - 1);
  76.             }
  77.             else if (i > 0)
  78.             {
  79.                 str.erase(0, i);
  80.             }
  81.         }
  82.         else
  83.         {
  84.             i = 0;
  85.             while (str[i] != '.')
  86.             {
  87.                 if (str[i] != '0')
  88.                 {
  89.                     break;
  90.                 }
  91.                 i++;
  92.             }
  93.             if (i == str.find('.'))
  94.             {
  95.                 str.erase(0, i - 1);
  96.             }
  97.             else if (i > 0)
  98.             {
  99.                 str.erase(0, i);
  100.             }
  101.             i = str.size() - 1;
  102.             while (str[i] != '.')
  103.             {
  104.                 if (str[i] != '0')
  105.                 {
  106.                     break;
  107.                 }
  108.                 i--;
  109.             }
  110.             if (i == str.find('.'))
  111.             {
  112.                 str.erase(i);
  113.             }
  114.             else if (i < str.size() - 1)
  115.             {
  116.                 str.erase(i + 1);
  117.             }
  118.         }
  119.     }
  120.     if (s[0] == '-' && str != "0")
  121.     {
  122.         str.insert(0, 1, '-');
  123.     }
  124. return str;
  125. }
  126. //(4)转换数组
  127. const vector<int> lnum::strToVec(const string &s) const
  128. {
  129.     vector<int> vint;
  130.     string str = s;
  131.     str[0] == '-' ? str.erase(0, 1) : str;
  132.     hasDecPoint(str) > false ? str.erase(str.find('.'), 1) : str;
  133.     for (char c : str)
  134.     {
  135.         vint.push_back(c - 48);
  136.     }
  137.     return vint;
  138. }
  139. //(-4)转换字符串
  140. const string lnum::vecToStr(const vector<int> &vint, int sgn, size_t dsz) const
  141. {
  142.     string str;
  143.     for (int i : vint)
  144.     {
  145.         str.push_back(i + 48);
  146.     }
  147.     if (str != "0")
  148.     {
  149.         dsz == 0 ? str : str.insert(str.size() - dsz, 1, '.');
  150.         sgn == -1 ? str.insert(0, 1, '-') : str;
  151.     }
  152.     return str;
  153. }
  154. //(5)提取信息
  155. const lnum::ndata lnum::getInfo(const string &s) const
  156. {
  157.     ndata ndt = {0, "0", {0}, 1, 0};
  158.     if (isInvalidStr(s))
  159.     {
  160.         ndt.nstr = s;
  161.         ndt.sign = ndt.nstr != "0" ? (ndt.nstr[0] == '-' ? -1 : 1) : 0;
  162.         ndt.dsize = hasDecPoint(ndt.nstr) || false ? ndt.nstr.size() - ndt.nstr.find('.') - 1 : 0;
  163.         ndt.nvec = strToVec(ndt.nstr);
  164.         ndt.isize = ndt.nvec.size() - ndt.dsize;
  165.     }
  166.     return ndt;
  167. }
  168. //(6)小数位对齐
  169. lnum::align lnum::dAlign(const lnum &l) const
  170. {
  171.     align agn;
  172.     vector<int> &f = agn.first, &s = agn.second;
  173.     f = data.nvec;
  174.     s = l.data.nvec;
  175.     const size_t &fds = data.dsize, &sds = l.data.dsize;
  176.     fds > sds ? s.insert(s.end(), fds - sds, 0) : f.insert(f.end(), sds - fds, 0);
  177.     return agn;
  178. }
  179. //(7)整体对齐
  180. lnum::align lnum::wAlign(const lnum &l) const
  181. {
  182.     align &&agn = this->dAlign(l);
  183.     vector<int> &f = agn.first, &s = agn.second;
  184.     const size_t &fws = data.isize, &sws = l.data.isize;
  185.     fws > sws ? s.insert(s.begin(), fws - sws, 0) : f.insert(f.begin(), sws - fws, 0);
  186.     return agn;
  187. }
  188. //(8)满十进一
  189. void lnum::carry(vector<int> &v) const
  190. {
  191.     v.insert(v.begin(), 1, 0);
  192.     const size_t s = v.size();
  193.     for (size_t i = s - 1; i != 0; i--)
  194.     {
  195.         int t = v[i];
  196.         v[i] = t % 10;
  197.         v[i - 1] += t / 10;
  198.     }
  199.     if (v[0] == 0)
  200.     {
  201.         v.erase(v.begin(), v.begin() + 1);
  202.     }
  203. }
  204. //(9)借一补十
  205. void lnum::borrow(vector<int> &v) const
  206. {
  207.     const size_t s = v.size();
  208.     for (size_t i = 1; i < s; i++)
  209.     {
  210.         v[i - 1] -= 1;
  211.         v[i] += 10;
  212.     }
  213. }
  214. //(10)输出设置
  215. const string lnum::setPrint() const
  216. {
  217.     const size_t &tds = data.dsize;
  218.     string str = data.nstr;
  219.     if (pre == 0)
  220.     {
  221.         if (tds != 0)
  222.         {
  223.             str.erase(str.find('.'));
  224.         }
  225.     }
  226.     else if (tds > pre)
  227.     {

  228.         str.erase(str.size() - (tds - pre));
  229.     }
  230.     return clearInvalidZero(str);
  231. }
  232. //(11)lnum*n
  233. const lnum lnum::operator*(const int &n) const
  234. {
  235.     vector<int> t = data.nvec;
  236.     for (int &i : t)
  237.     {
  238.         i *= n;
  239.     }
  240.     carry(t);
  241.     lnum r = vecToStr(t, data.sign, data.dsize);
  242.     return r;
  243. }
  244. //==========================================================================
  245. //(0)显示信息
  246. void lnum::showinfo() const
  247. {
  248.     std::cout << "正/负/零: " << data.sign << "\n"
  249.               << "原始数字: " << data.nstr << "\n"
  250.               << "数组元素: ";
  251.     for (int i : data.nvec)
  252.     {
  253.         std::cout << i << " ";
  254.     }
  255.     std::cout << std::endl;
  256.     std::cout << "整数位数: " << data.isize << "\n"
  257.               << "小数位数: " << data.dsize << std::endl;
  258. }
  259. void lnum::setprecision(const size_t p)
  260. {
  261.     pre = p;
  262. }
  263. //(1)>号
  264. const bool lnum::operator>(const lnum &l) const
  265. {
  266.     bool f = true;
  267.     const int &tsgn = data.sign, &lsgn = l.data.sign;
  268.     if (tsgn < lsgn)
  269.     {
  270.         f = false;
  271.     }
  272.     else if (tsgn == lsgn)
  273.     {
  274.         const align &agn = this->wAlign(l);
  275.         f = agn.first > agn.second;
  276.         if (tsgn == -1)
  277.         {
  278.             f = !f;
  279.         }
  280.     }
  281.     return f;
  282. }
  283. //(2)==
  284. const bool lnum::operator==(const lnum &l) const
  285. {
  286.     return (data.sign == l.data.sign) && (data.nvec == l.data.nvec);
  287. }
  288. //(3)>=
  289. const bool lnum::operator>=(const lnum &l) const
  290. {
  291.     return (*this > l) || (*this == l);
  292. }
  293. //(4)<
  294. const bool lnum::operator<(const lnum &l) const
  295. {
  296.     return !(*this >= l);
  297. }
  298. //(5)<=
  299. const bool lnum::operator<=(const lnum &l) const
  300. {
  301.     return (*this < l) || (*this == l);
  302. }
  303. //(5.5)!=
  304. const bool lnum::operator!=(const lnum &l) const
  305. {
  306.     return !(*this == l);
  307. }
  308. //(6)+
  309. const lnum lnum::operator+(const lnum &l) const
  310. {
  311.     lnum r;
  312.     if (*this != (-l))
  313.     {
  314.         align agn = this->wAlign(l);
  315.         vector<int> &fst = agn.first,
  316.                     &sec = agn.second,
  317.                     &greater = fst >= sec ? fst : sec,
  318.                     &less = sec <= fst ? sec : fst;
  319.         const int &tsgn = data.sign,
  320.                   &lsgn = l.data.sign;
  321.         const size_t &sz = fst.size();
  322.         for (size_t i = 0; i < sz; i++)
  323.         {
  324.             greater[i] += (lsgn * tsgn) * less[i];
  325.         }
  326.         int sgn = 1;
  327.         if (tsgn == lsgn)
  328.         {
  329.             sgn = tsgn;
  330.         }
  331.         else if (tsgn != lsgn)
  332.         {
  333.             sgn = ((greater == fst && tsgn < lsgn) || (less == fst && tsgn > lsgn)) || false ? -1 : sgn;
  334.         }
  335.         if (tsgn * lsgn == -1)
  336.         {
  337.             borrow(greater);
  338.         }
  339.         carry(greater);
  340.         size_t dsz = data.dsize >= l.data.dsize ? data.dsize : l.data.dsize;
  341.         //string str = vecToStr(greater, sgn, dsz);
  342.         r = vecToStr(greater, sgn, dsz);
  343.     }
  344.     return r;
  345. }

  346. //(7)-反转正负
  347. const lnum lnum::operator-() const
  348. {
  349.     lnum r = *this;
  350.     if (data.sign != 0)
  351.     {
  352.         r.data.sign = -data.sign;
  353.         r.data.nstr = vecToStr(data.nvec, -data.sign, data.dsize);
  354.     }
  355.     return r;
  356. }
  357. //(7.5)-
  358. const lnum lnum::operator-(const lnum &l) const
  359. {
  360.     return *this + (-l);
  361. }
  362. //(8)+=
  363. const lnum &lnum::operator+=(const lnum &l)
  364. {
  365.     return *this = *this + l;
  366. }
  367. //(9)++
  368. const lnum &lnum::operator++(const int i)
  369. {
  370.     return *this = *this + "1";
  371. }
  372. //(10)-=
  373. const lnum &lnum::operator-=(const lnum &l)
  374. {
  375.     return *this = *this + (-l);
  376. }
  377. //(11)--
  378. const lnum &lnum::operator--(const int i)
  379. {
  380.     return *this = *this + "-1";
  381. }
  382. //(12)lnum*lnum
  383. const lnum lnum::operator*(const lnum &l) const
  384. {
  385.     lnum r;
  386.     const int &tsgn = data.sign,
  387.               &lsgn = l.data.sign;
  388.     if (tsgn * lsgn == 0)
  389.     {
  390.         r = "0";
  391.     }
  392.     else
  393.     {
  394.         const vector<int> &tvec = data.nvec,
  395.                           &lvec = l.data.nvec;
  396.         const size_t &tsz = data.dsize,
  397.                      &lsz = l.data.dsize,
  398.                      &tvsz = tvec.size(),
  399.                      &lvsz = lvec.size(),
  400.                      &shrtsz = tvsz <= lvsz ? tvsz : lvsz;
  401.         lnum loong = tvsz >= lvsz ? *this : l;
  402.         const vector<int> &shrtv = lvsz <= tvsz ? lvec : tvec;
  403.         vector<int> &lovec = loong.data.nvec,
  404.                     &rvec = r.data.nvec;
  405.         for (size_t i = shrtsz - 1; i != -1; i--)
  406.         {
  407.             r += loong * shrtv[i];
  408.             if (i > 0)
  409.             {
  410.                 lovec.push_back(0);
  411.             }
  412.         }
  413.         r = vecToStr(rvec, tsgn * lsgn, tsz + lsz);
  414.     }
  415.     return r;
  416. }
  417. //(F)<<
  418. ostream &operator<<(ostream &os, const lnum &l)
  419. {
  420.     os << l.setPrint();
  421.     return os;
  422. }
  423. //(F)>>
  424. istream &operator>>(istream &is, lnum &l)
  425. {
  426.     string str;
  427.     (std::cin >> str).get();
  428.     l = str;
  429.     return is;
  430. }
复制代码


===========================================
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-12 07:48

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表