鱼C论坛

 找回密码
 立即注册
查看: 1876|回复: 5

[技术交流] 大数计算加减法

[复制链接]
发表于 2019-12-28 20:01:22 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 bin554385863 于 2019-12-28 20:30 编辑

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.     struct attr
  13.     {
  14.         int sign = 1;          //符号;
  15.         size_t dpsize = 0;     //小数位;
  16.         size_t prec = 0;       //精度
  17.         size_t nsize = 1;      //有效位数
  18.         string str = "0";      //过渡字符串
  19.         vector<int> vec = {0}; //数组;
  20.     };
  21.     struct align
  22.     {
  23.         vector<int> first;

  24.         vector<int> second;
  25.     };

  26. private:
  27.     //小数精度;
  28.     static size_t precision;
  29.     //数据;
  30.     attr num;
  31.     //str to attr
  32.     const attr StrToAttr(const string &str) const;
  33.     //attr to str
  34.     const string AttrToStr() const;
  35.     //进1
  36.     lnum &Carry();
  37.     //借1
  38.     vector<int> Borrow() const;
  39.     //对齐
  40.     const align AlignVec(const vector<int> &m, const vector<int> &n) const;
  41.     //反转正负
  42.     vector<int> Negative() const;
  43.     //clear zero vec
  44.     lnum &ClearZeroVec();
  45.     //vec to str
  46.     lnum &VecToStr();

  47. public:
  48.     lnum(const char *cstr = "0") : num(StrToAttr(cstr))
  49.     {
  50.     }
  51.     lnum(const string &str) : num(StrToAttr(str)) {}
  52.     lnum(const lnum &l) : num(l.num) {}
  53.     //------------------------------------------------------------------
  54.     //设置精度
  55.     static void SetPrecision(const size_t i);
  56.     //展示信息
  57.     void Showinfo() const;
  58.     //>
  59.     const bool operator>(const lnum &l) const;
  60.     //<
  61.     const bool operator<(const lnum &l) const;
  62.     //==
  63.     const bool operator==(const lnum &l) const;
  64.     //>=
  65.     const bool operator>=(const lnum &l) const;
  66.     //<=
  67.     const bool operator<=(const lnum &l) const;
  68.     //+
  69.     const lnum operator+(const lnum &l) const;
  70.     //-
  71.     const lnum operator-(const lnum &l) const;
  72.     //>>
  73.     friend istream &operator>>(istream &is, const lnum &l);
  74.     //<<
  75.     friend ostream &operator<<(ostream &os, const lnum &l);
  76. };
  77. size_t lnum::precision = 0;
  78. #endif
复制代码


lnum.cpp
  1. #include "E:\Users\admin\Documents\VScode\Code\My Class\shape.cpp\lnum\lnum.h"
  2. //str to attr
  3. const lnum::attr lnum::StrToAttr(const string &str) const
  4. {
  5.     attr n;
  6.     n.prec = precision;
  7.     n.str = str;
  8.     string &nstr = n.str;
  9.     if (nstr[0] == '-')
  10.     {
  11.         nstr.erase(0, 1);
  12.     }
  13.     if (int(nstr.find('.')) != -1)
  14.     {
  15.         nstr.erase(nstr.find('.'), 1);
  16.     }
  17.     if (nstr == string(nstr.size(), '0'))
  18.     {
  19.         nstr.clear();
  20.         nstr.push_back('0');
  21.     }
  22.     else if (nstr != string(nstr.size(), '0'))
  23.     {
  24.         size_t s = nstr.size(), i = 0;
  25.         if (str[0] == '-')
  26.         {
  27.             n.sign = -1;
  28.         }
  29.         if (int(str.find('.')) != -1)
  30.         {
  31.             n.dpsize = str.size() - str.find('.') - 1;
  32.             if (nstr[0] == '0')
  33.             {

  34.                 for (; i < s; i++)
  35.                 {
  36.                     if (nstr[i] != '0')
  37.                     {
  38.                         break;
  39.                     }
  40.                 }
  41.                 if (i >= s - n.dpsize)
  42.                 {
  43.                     nstr.erase(0, s - n.dpsize - 1);
  44.                 }
  45.                 else if (i < s - n.dpsize)
  46.                 {
  47.                     nstr.erase(0, i);
  48.                 }
  49.             }
  50.         }
  51.         else
  52.         {
  53.             if (nstr[0] == '0')
  54.             {
  55.                 for (i = 0; i < s; i++)
  56.                 {
  57.                     if (nstr[i] != '0')
  58.                     {
  59.                         break;
  60.                     }
  61.                 }
  62.                 nstr.erase(0, i);
  63.             }
  64.         }
  65.         if (n.prec > n.dpsize)
  66.         {
  67.             nstr.insert(nstr.end(), n.prec - n.dpsize, '0');
  68.         }
  69.         else if (n.prec < n.dpsize)
  70.         {
  71.             nstr.erase(nstr.size() - (n.dpsize - n.prec));
  72.             n.dpsize = n.prec;
  73.         }
  74.         n.vec.clear();
  75.         for (char c : nstr)
  76.         {
  77.             n.vec.push_back(c - 48);
  78.         }
  79.         n.nsize = nstr.size();
  80.     }
  81.     return n;
  82. }
  83. //attr to str
  84. const string lnum::AttrToStr() const
  85. {
  86.     string str = num.str;
  87.     const size_t &prec = num.prec, &dpsize = num.dpsize;
  88.     if (str.size() != 1 && prec != 0)
  89.     {
  90.         if (dpsize == prec)
  91.         {
  92.             str.insert(str.size() - prec, 1, '.');
  93.         }
  94.         else if (dpsize < prec && dpsize != 0)
  95.         {
  96.             str.erase(str.size() - (prec - dpsize));
  97.             str.insert(str.size() - dpsize, 1, '.');
  98.         }
  99.         else if (dpsize == 0)
  100.         {
  101.             str.erase(str.size() - prec);
  102.         }
  103.     }
  104.     if (num.sign == -1)
  105.     {
  106.         str.insert(0, 1, '-');
  107.     }
  108.     return str;
  109. }
  110. //进1
  111. lnum &lnum::Carry()
  112. {
  113.     vector<int> &v = num.vec;
  114.     v.insert(v.begin(), 1, 0);
  115.     size_t s = v.size();
  116.     for (size_t i = s - 1; i > 0; i--)
  117.     {
  118.         int t = v[i];
  119.         v[i] = t % 10;
  120.         v[i - 1] += t / 10;
  121.     }
  122.     return *this;
  123. }
  124. //借1
  125. vector<int> lnum::Borrow() const
  126. {
  127.     vector<int> t = num.vec;
  128.     size_t s = t.size();
  129.     for (size_t i = 1; i < s; i++)
  130.     {
  131.         t[i - 1] -= 1;
  132.         t[i] += 10;
  133.     }
  134.     return t;
  135. }
  136. //对齐
  137. const lnum::align lnum::AlignVec(const vector<int> &m, const vector<int> &n) const
  138. {
  139.     align agn;
  140.     vector<int> &fst = agn.first, &sec = agn.second;
  141.     fst = m, sec = n;
  142.     size_t fsize = fst.size(), ssize = sec.size();
  143.     if (fsize < ssize)
  144.     {
  145.         fst.insert(fst.begin(), ssize - fsize, 0);
  146.     }
  147.     else if (fsize > ssize)
  148.     {
  149.         sec.insert(sec.begin(), fsize - ssize, 0);
  150.     }
  151.     return agn;
  152. }
  153. //反转正负
  154. vector<int> lnum::Negative() const
  155. {
  156.     auto r = num.vec;
  157.     for (int &i : r)
  158.     {
  159.         i = -1;
  160.     }
  161.     return r;
  162. }
  163. //clear zero vec
  164. lnum &lnum::ClearZeroVec()
  165. {
  166.     const size_t &prec = num.prec;
  167.     vector<int> &v = num.vec;
  168.     if (v == vector<int>(v.size(), 0))
  169.     {
  170.         v.clear();
  171.         v.push_back(0);
  172.     }
  173.     else if (v[0] == 0)
  174.     {
  175.         size_t s = v.size(), i = 0;
  176.         if (prec != 0)
  177.         {
  178.             
  179.             for (; i < s; i++)
  180.             {
  181.                 if (v[i] != 0)
  182.                 {
  183.                     break;
  184.                 }
  185.             }
  186.             if (i >= s - prec)
  187.             {
  188.                 v.erase(v.begin(), v.begin() + (s - prec - 1));
  189.             }
  190.             else if (i < s - prec)
  191.             {
  192.                 v.erase(v.begin(), v.begin() + i);
  193.             }
  194.         }
  195.         else
  196.         {
  197.             for ( i = 0; i < s; i++)
  198.             {
  199.                 if (v[i] != 0)
  200.                 {
  201.                     break;
  202.                 }
  203.             }
  204.             v.erase(v.begin(), v.begin() + i);
  205.         }
  206.         
  207.     }
  208.     return *this;
  209. }
  210. //vec to str
  211. lnum &lnum::VecToStr()
  212. {
  213.     num.str.clear();
  214.     for (int i : num.vec)
  215.     {
  216.         num.str.push_back(i + 48);
  217.     }
  218.     return *this;
  219. }
  220. //------------------------------------------------------------------------
  221. //设置精度
  222. void lnum::SetPrecision(const size_t i)
  223. {
  224.     lnum::precision = i;
  225. }
  226. //展示信息
  227. void lnum::Showinfo() const
  228. {
  229.     std::cout << "有效数位: ";
  230.     for (int i : num.vec)
  231.     {
  232.         std::cout << i << " ";
  233.     }
  234.     std::cout << std::endl;
  235.     std::cout << "正负符号: " << num.sign << "\n"
  236.               << "小数位数: " << num.dpsize << "\n"
  237.               << "小数精度: " << num.prec << "\n"
  238.               << "有效位数: " << num.nsize << std::endl;
  239. }
  240. //>
  241. const bool lnum::operator>(const lnum &l) const
  242. {
  243.     bool f = true;
  244.     align agn = AlignVec(num.vec, l.num.vec);
  245.     const vector<int> &fst = agn.first, &sec = agn.second;
  246.     if (num.sign < l.num.sign)
  247.     {
  248.         f = false;
  249.     }
  250.     if (num.sign == l.num.sign)
  251.     {
  252.         f = fst > sec;
  253.         if (num.sign == -1)
  254.         {
  255.             f = !f;
  256.         }
  257.     }
  258.     return f;
  259. }
  260. //<
  261. const bool lnum::operator<(const lnum &l) const
  262. {
  263.     bool f = true;
  264.     align agn = AlignVec(num.vec, l.num.vec);
  265.     const vector<int> &fst = agn.first, &sec = agn.second;
  266.     if (num.sign > l.num.sign)
  267.     {
  268.         f = false;
  269.     }
  270.     if (num.sign == l.num.sign)
  271.     {
  272.         f = fst < sec;
  273.         if (num.sign == -1)
  274.         {
  275.             f = !f;
  276.         }
  277.     }
  278.     return f;
  279. }
  280. //==
  281. const bool lnum::operator==(const lnum &l) const
  282. {
  283.     align agn = AlignVec(num.vec, l.num.vec);
  284.     const vector<int> &fst = agn.first, &sec = agn.second;
  285.     return fst == sec && num.sign == l.num.sign;
  286. }
  287. //>=
  288. const bool lnum::operator>=(const lnum &l) const
  289. {
  290.     return !(*this < l);
  291. }
  292. //<=
  293. const bool lnum::operator<=(const lnum &l) const
  294. {
  295.     return !(*this > l);
  296. }
  297. //+
  298. const lnum lnum::operator+(const lnum &l) const
  299. {

  300.     lnum r;
  301.     attr &lr = r.num;
  302.     const size_t &prec = num.prec, &dpsize = num.dpsize, &ldps = l.num.dpsize;
  303.     if ((num.vec == vector<int>(1, 0)) && (l.num.vec == vector<int>(1, 0)))
  304.     {
  305.         lr.prec = num.prec;
  306.     }
  307.     else if ((num.vec != vector<int>(1, 0)) || (l.num.vec != vector<int>(1, 0)))
  308.     {
  309.         const align &agn = AlignVec(num.vec, l.num.vec);
  310.         const vector<int> &fst = agn.first,
  311.                           &sec = agn.second,
  312.                           &tvec = this->num.vec,
  313.                           &lvec = l.num.vec;
  314.         lr.prec = prec;
  315.         lr.dpsize = dpsize >= ldps ? dpsize : ldps;
  316.         if (num.sign == l.num.sign)
  317.         {
  318.             lr.sign = num.sign;
  319.             if (((tvec == vector<int>(1, 0)) && (lvec != vector<int>(1, 0))) ||((tvec != vector<int>(1, 0)) && (lvec == vector<int>(1, 0))))
  320.             {
  321.                 lr.vec = num.nsize > l.num.nsize ? tvec : lvec;
  322.             }
  323.             else if ((tvec != vector<int>(1, 0)) && (lvec != vector<int>(1, 0)))
  324.             {
  325.                 size_t s = fst.size();
  326.                 lr.vec = fst;
  327.                 for (size_t i = 0; i < s; i++)
  328.                 {
  329.                     lr.vec[i] += sec[i];
  330.                 }
  331.             }
  332.             r.Carry().ClearZeroVec().VecToStr();
  333.             lr.nsize = lr.vec.size();
  334.         }
  335.         else
  336.         {
  337.             r = *this - l;
  338.         }
  339.     }
  340.     return r;
  341. }
  342. //-
  343. const lnum lnum::operator-(const lnum &l) const
  344. {
  345. }
  346. //>>
  347. istream &operator>>(istream &is, lnum &l)
  348. {
  349.     string str;
  350.     (is >> str).get();
  351.     l = str;
  352.     return is;
  353. }
  354. //<<
  355. ostream &operator<<(ostream &os, const lnum &l)
  356. {
  357.     os << l.AttrToStr();
  358.     return os;
  359. }
复制代码


lnum_test.cpp
  1. #include "E:\Users\admin\Documents\VScode\Code\My Class\shape.cpp\lnum\lnum.cpp"
  2. int main(int argc, char const *argv[])
  3. {
  4.     lnum::SetPrecision(3);
  5.     lnum a, b, c;
  6.     int i = 0;
  7.     while (i != 5)
  8.     {
  9.         std::cout << "input data\n";
  10.         std::cin >> a >> b;
  11.         std::cout << "a = " << a << "  "
  12.                   << "b = " << b << "\n"
  13.                   << "a + b = " << (a + b) << std::endl;
  14.                   std::cout << std::endl;
  15.         i++;
  16.     }
  17.    
  18.     return 0;
  19. }
复制代码

======================================================
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-hjg4v2n2.0lr --stdout=Microsoft-MIEngine-Out-ggdaz51y.hrw --stderr=Microsoft-MIEngine-Error-1w25bxep.ub3 --pid=Microsoft-MIEngine-Pid-pa4lnrzg.3fq --dbgExe=D:\MinGW\bin\gdb.exe --interpreter=mi

E:\Users\admin\Documents\VScode\Code>cmd /C "c:\Users\admin\.vscode\extensions\ms-vscode.cpptools-0.26.2\debugAdapters\bin\WindowsDebugLauncher.exe --stdin=Microsoft-MIEngine-In-rdahdasn.3vx --stdout=Microsoft-MIEngine-Out-2nxw4ara.tc2 --stderr=Microsoft-MIEngine-Error-b5yp3gag.nte --pid=Microsoft-MIEngine-Pid-twogf14w.0fy --dbgExe=D:\MinGW\bin\gdb.exe --interpreter=mi "
input data
-999.321 -111.123
a = -999.321  b = -111.123
a + b = -1110.444

input data
123456789
987654321
a = 123456789  b = 987654321
a + b = 1111111110

input data
1111111111111111111111111
3333333333333333333333333
a = 1111111111111111111111111  b = 3333333333333333333333333
a + b = 4444444444444444444444444

input data
999999999999
999999999999
a = 999999999999  b = 999999999999
a + b = 1999999999998

input data
987654321
12345679
a = 987654321  b = 12345679
a + b = 1000000000



E:\Users\admin\Documents\VScode\Code>cmd /C "c:\Users\admin\.vscode\extensions\ms-vscode.cpptools-0.26.2\debugAdapters\bin\WindowsDebugLauncher.exe --stdin=Microsoft-MIEngine-In-dlfxekp3.bym --stdout=Microsoft-MIEngine-Out-jtwn51h5.ubn --stderr=Microsoft-MIEngine-Error-rc5va4if.ni3 --pid=Microsoft-MIEngine-Pid-xrrvgcs4.jrr --dbgExe=D:\MinGW\bin\gdb.exe --interpreter=mi "
input data
-9999999999999999999999
-9999999999999999999999
a = -9999999999999999999999  b = -9999999999999999999999
a + b = -19999999999999999999998

input data
-99999999999999999999999999999999999999999
-99999999999999999999999999999999999999999
a = -99999999999999999999999999999999999999999  b = -99999999999999999999999999999999999999999
a + b = -199999999999999999999999999999999999999998

input data
9999999999999999999999999999999999999999999999999999
9999999999999999999999999999999999999999999999999999
a = 9999999999999999999999999999999999999999999999999999  b = 9999999999999999999999999999999999999999999999999999
a + b = 19999999999999999999999999999999999999999999999999998

input data
111111111111111111111111111111111111111.1111111111111111111111
99999999999999999999999999999999999.9999999999999999999999
a = 111111111111111111111111111111111111111.111  b = 99999999999999999999999999999999999.999
a + b = 111211111111111111111111111111111111111.110

input data
-1.2366666
-9.3654
a = -1.236  b = -9.365
a + b = -10.601


E:\Users\admin\Documents\VScode\Code>


-------------------------------------------------------------------------------------------------
test.cpp

  1. #include "E:\Users\admin\Documents\VScode\Code\My Class\shape.cpp\lnum\lnum.cpp"
  2. int main(int argc, char const *argv[])
  3. {
  4.     lnum::SetPrecision(3);
  5.     lnum a, b, c;
  6.     int i = 0;
  7.     while (i != 5)
  8.     {
  9.         std::cout << "input data\n";
  10.         std::cin >> a >> b;
  11.         std::cout << std::boolalpha << "a = " << a << "  "
  12.                   << "b = " << b << "\n"
  13.                   << "a >= b: " << (a >= b) << "\n"
  14.                   << "a >  b: " << (a > b) << "\n"
  15.                   << "a <= b: " << (a <= b) << "\n"
  16.                   << "a <  b: " << (a < b) << "\n"
  17.                   << "a == b: " << (a == b);
  18.         std::cout << std::endl;
  19.         i++;
  20.     }
  21.    
  22.     return 0;
  23. }
复制代码

================================================
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-zcwtj5dz.rhq --stdout=Microsoft-MIEngine-Out-rmj34qps.1zn --stderr=Microsoft-MIEngine-Error-opbzjopy.skk --pid=Microsoft-MIEngine-Pid-t23shlyh.4d2 --dbgExe=D:\MinGW\bin\gdb.exe --interpreter=mi
input data
0
0.01
a = 0  b = 0.01
a >= b: false  
a >  b: false  
a <= b: true   
a <  b: true   
a == b: false  
input data     
0
0
a = 0  b = 0
a >= b: true
a >  b: false
a <= b: true
a <  b: false
a == b: true
input data
99999999999999999999999999
66666666666666666666666666
a = 99999999999999999999999999  b = 66666666666666666666666666
a >= b: true
a >  b: true
a <= b: false
a <  b: false
a == b: false
input data
11111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111112
a = 11111111111111111111111111111111111111111111111111  b = 11111111111111111111111111111111111111111111111112
a >= b: false
a >  b: false
a <= b: true
a <  b: true
a == b: false
input data
0.02
0.03
a = 0.02  b = 0.03
a >= b: false
a >  b: false
a <= b: true
a <  b: true
a == b: false


E:\Users\admin\Documents\VScode\Code>
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2019-12-29 03:16:31 | 显示全部楼层
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.     struct attr
  13.     {
  14.         int sign = 1;          //符号;
  15.         size_t dpsize = 0;     //小数位;
  16.         size_t prec = 0;       //精度
  17.         size_t nsize = 1;      //有效位数
  18.         string str = "0";      //过渡字符串
  19.         vector<int> vec = {0}; //数组;
  20.     };
  21.     struct align
  22.     {
  23.         vector<int> first;

  24.         vector<int> second;
  25.     };

  26. private:
  27.     //小数精度;
  28.     static size_t precision;
  29.     //数据;
  30.     attr num;
  31.     //str to attr
  32.     const attr StrToAttr(const string &str) const;
  33.     //attr to str
  34.     const string AttrToStr() const;
  35.     //进1
  36.     lnum &Carry();
  37.     //借1
  38.     void Borrow(vector<int> &v) const;
  39.     //对齐
  40.     const align AlignVec(const vector<int> &m, const vector<int> &n) const;
  41.     //反转正负
  42.     const lnum Negative() const;
  43.     //clear zero vec
  44.     lnum &ClearZeroVec();
  45.     //vec to str
  46.     lnum &VecToStr();

  47. public:
  48.     lnum(const char *cstr = "0") : num(StrToAttr(cstr)){}
  49.     lnum(const string &str) : num(StrToAttr(str)) {}
  50.     lnum(const char c) : num(StrToAttr(string(1, c))) {}
  51.     lnum(const lnum &l) : num(l.num) {}
  52.     //------------------------------------------------------------------
  53.     //设置精度
  54.     static void SetPrecision(const size_t i);
  55.     //展示信息
  56.     void Showinfo() const;
  57.     //>
  58.     const bool operator>(const lnum &l) const;
  59.     //<
  60.     const bool operator<(const lnum &l) const;
  61.     //==
  62.     const bool operator==(const lnum &l) const;
  63.     //>=
  64.     const bool operator>=(const lnum &l) const;
  65.     //<=
  66.     const bool operator<=(const lnum &l) const;
  67.     //+
  68.     const lnum operator+(const lnum &l) const;
  69.     //-
  70.     const lnum operator-(const lnum &l) const;
  71.     //>>
  72.     friend istream &operator>>(istream &is, const lnum &l);
  73.     //<<
  74.     friend ostream &operator<<(ostream &os, const lnum &l);
  75. };
  76. size_t lnum::precision = 0;
  77. #endif
复制代码


lnum.cpp

  1. #include "E:\Users\admin\Documents\VScode\Code\My Class\shape.cpp\lnum\lnum.h"
  2. //str to attr
  3. const lnum::attr lnum::StrToAttr(const string &str) const
  4. {
  5.     attr n;
  6.     n.prec = precision;
  7.     n.str = str;
  8.     string &nstr = n.str;
  9.     if (nstr[0] == '-')
  10.     {
  11.         nstr.erase(0, 1);
  12.     }
  13.     if (int(nstr.find('.')) != -1)
  14.     {
  15.         nstr.erase(nstr.find('.'), 1);
  16.     }
  17.     if (nstr == string(nstr.size(), '0'))
  18.     {
  19.         nstr.clear();
  20.         nstr.push_back('0');
  21.     }
  22.     else //if (nstr != string(nstr.size(), '0'))
  23.     {
  24.         size_t s = nstr.size(), i = 0;
  25.         if (str[0] == '-')
  26.         {
  27.             n.sign = -1;
  28.         }
  29.         if (int(str.find('.')) != -1)
  30.         {
  31.             n.dpsize = str.size() - str.find('.') - 1;
  32.             if (nstr[0] == '0')
  33.             {

  34.                 for (; i < s; i++)
  35.                 {
  36.                     if (nstr[i] != '0')
  37.                     {
  38.                         break;
  39.                     }
  40.                 }
  41.                 if (i >= s - n.dpsize)
  42.                 {
  43.                     nstr.erase(0, s - n.dpsize - 1);
  44.                 }
  45.                 else if (i < s - n.dpsize)
  46.                 {
  47.                     nstr.erase(0, i);
  48.                 }
  49.             }
  50.         }
  51.         else
  52.         {
  53.             if (nstr[0] == '0')
  54.             {
  55.                 for (i = 0; i < s; i++)
  56.                 {
  57.                     if (nstr[i] != '0')
  58.                     {
  59.                         break;
  60.                     }
  61.                 }
  62.                 nstr.erase(0, i);
  63.             }
  64.         }
  65.         if (n.prec > n.dpsize)
  66.         {
  67.             nstr.insert(nstr.end(), n.prec - n.dpsize, '0');
  68.         }
  69.         else if (n.prec < n.dpsize)
  70.         {
  71.             nstr.erase(nstr.size() - (n.dpsize - n.prec));
  72.             n.dpsize = n.prec;
  73.         }
  74.         n.vec.clear();
  75.         for (char c : nstr)
  76.         {
  77.             n.vec.push_back(c - 48);
  78.         }
  79.         n.nsize = nstr.size();
  80.     }
  81.     return n;
  82. }
  83. //attr to str
  84. const string lnum::AttrToStr() const
  85. {
  86.     string str = num.str;
  87.     const size_t &prec = num.prec, &dpsize = num.dpsize;
  88.     if (str.size() != 1 && prec != 0)
  89.     {
  90.         if (dpsize == prec)
  91.         {
  92.             str.insert(str.size() - prec, 1, '.');
  93.         }
  94.         else if (dpsize < prec && dpsize != 0)
  95.         {
  96.             str.erase(str.size() - (prec - dpsize));
  97.             str.insert(str.size() - dpsize, 1, '.');
  98.         }
  99.         else if (dpsize == 0)
  100.         {
  101.             str.erase(str.size() - prec);
  102.         }
  103.     }
  104.     if (num.sign == -1)
  105.     {
  106.         str.insert(0, 1, '-');
  107.     }
  108.     return str;
  109. }
  110. //进1
  111. lnum &lnum::Carry()
  112. {
  113.     vector<int> &v = num.vec;
  114.     v.insert(v.begin(), 1, 0);
  115.     size_t s = v.size();
  116.     for (size_t i = s - 1; i > 0; i--)
  117.     {
  118.         int t = v[i];
  119.         v[i] = t % 10;
  120.         v[i - 1] += t / 10;
  121.     }
  122.     return *this;
  123. }
  124. //借1
  125. void lnum::Borrow(vector<int> &v) const
  126. {
  127.     size_t s = v.size();
  128.     for (size_t i = 1; i < s; i++)
  129.     {
  130.         v[i - 1] -= 1;
  131.         v[i] += 10;
  132.     }
  133. }
  134. //对齐
  135. const lnum::align lnum::AlignVec(const vector<int> &m, const vector<int> &n) const
  136. {
  137.     align agn;
  138.     vector<int> &fst = agn.first, &sec = agn.second;
  139.     fst = m, sec = n;
  140.     size_t fsize = fst.size(), ssize = sec.size();
  141.     if (fsize < ssize)
  142.     {
  143.         fst.insert(fst.begin(), ssize - fsize, 0);
  144.     }
  145.     else if (fsize > ssize)
  146.     {
  147.         sec.insert(sec.begin(), fsize - ssize, 0);
  148.     }
  149.     return agn;
  150. }
  151. //反转正负
  152. const lnum lnum::Negative() const
  153. {
  154.     lnum r = *this;
  155.     r.num.sign = -num.sign;
  156.     return r;
  157. }
  158. //clear zero vec
  159. lnum &lnum::ClearZeroVec()
  160. {
  161.     const size_t &prec = num.prec;
  162.     vector<int> &v = num.vec;
  163.     if (v == vector<int>(v.size(), 0))
  164.     {
  165.         v.clear();
  166.         v.push_back(0);
  167.     }
  168.     else if (v[0] == 0)
  169.     {
  170.         size_t s = v.size(), i = 0;
  171.         if (prec != 0)
  172.         {

  173.             for (; i < s; i++)
  174.             {
  175.                 if (v[i] != 0)
  176.                 {
  177.                     break;
  178.                 }
  179.             }
  180.             if (i >= s - prec)
  181.             {
  182.                 v.erase(v.begin(), v.begin() + (s - prec - 1));
  183.             }
  184.             else if (i < s - prec)
  185.             {
  186.                 v.erase(v.begin(), v.begin() + i);
  187.             }
  188.         }
  189.         else
  190.         {
  191.             for (i = 0; i < s; i++)
  192.             {
  193.                 if (v[i] != 0)
  194.                 {
  195.                     break;
  196.                 }
  197.             }
  198.             v.erase(v.begin(), v.begin() + i);
  199.         }
  200.     }
  201.     return *this;
  202. }
  203. //vec to str
  204. lnum &lnum::VecToStr()
  205. {
  206.     num.str.clear();
  207.     for (int i : num.vec)
  208.     {
  209.         num.str.push_back(i + 48);
  210.     }
  211.     return *this;
  212. }
  213. //------------------------------------------------------------------------
  214. //设置精度
  215. void lnum::SetPrecision(const size_t i)
  216. {
  217.     lnum::precision = i;
  218. }
  219. //展示信息
  220. void lnum::Showinfo() const
  221. {
  222.     std::cout << "有效数位: ";
  223.     for (int i : num.vec)
  224.     {
  225.         std::cout << i << " ";
  226.     }
  227.     std::cout << std::endl;
  228.     std::cout << "正负符号: " << num.sign << "\n"
  229.               << "小数位数: " << num.dpsize << "\n"
  230.               << "小数精度: " << num.prec << "\n"
  231.               << "有效位数: " << num.nsize << std::endl;
  232. }
  233. //>
  234. const bool lnum::operator>(const lnum &l) const
  235. {
  236.     bool f = true;
  237.     align agn = AlignVec(num.vec, l.num.vec);
  238.     const vector<int> &fst = agn.first, &sec = agn.second;
  239.     if (num.sign < l.num.sign)
  240.     {
  241.         f = false;
  242.     }
  243.     if (num.sign == l.num.sign)
  244.     {
  245.         f = fst > sec;
  246.         if (num.sign == -1)
  247.         {
  248.             f = !f;
  249.         }
  250.     }
  251.     return f;
  252. }
  253. //<
  254. const bool lnum::operator<(const lnum &l) const
  255. {
  256.     bool f = true;
  257.     align agn = AlignVec(num.vec, l.num.vec);
  258.     const vector<int> &fst = agn.first, &sec = agn.second;
  259.     if (num.sign > l.num.sign)
  260.     {
  261.         f = false;
  262.     }
  263.     if (num.sign == l.num.sign)
  264.     {
  265.         f = fst < sec;
  266.         if (num.sign == -1)
  267.         {
  268.             f = !f;
  269.         }
  270.     }
  271.     return f;
  272. }
  273. //==
  274. const bool lnum::operator==(const lnum &l) const
  275. {
  276.     align agn = AlignVec(num.vec, l.num.vec);
  277.     const vector<int> &fst = agn.first, &sec = agn.second;
  278.     return fst == sec && num.sign == l.num.sign;
  279. }
  280. //>=
  281. const bool lnum::operator>=(const lnum &l) const
  282. {
  283.     return !(*this < l);
  284. }
  285. //<=
  286. const bool lnum::operator<=(const lnum &l) const
  287. {
  288.     return !(*this > l);
  289. }
  290. //+
  291. const lnum lnum::operator+(const lnum &l) const
  292. {

  293.     lnum r;
  294.     attr &lr = r.num;
  295.     const align &agn = AlignVec(num.vec, l.num.vec);
  296.     const int &tsgn = num.sign, &lsgn = l.num.sign;
  297.     const vector<int> &fst = agn.first, &sec = agn.second, &tvec = num.vec, &lvec = l.num.vec;
  298.     lr.prec = num.prec;
  299.     lr.dpsize = num.dpsize >= l.num.dpsize ? num.dpsize : l.num.dpsize;
  300.     size_t s = fst.size() <= sec.size() ? fst.size() : sec.size();
  301.     lr.vec = fst >= sec ? fst : sec;
  302.     for (size_t i = 0; i < s; i++)
  303.     {
  304.         lr.vec[i] += (tsgn * lsgn) * ((sec <= fst ? sec : fst)[i]);
  305.     }
  306.     if ((fst > sec && tsgn < lsgn) || (fst < sec && tsgn > lsgn) || (tsgn == -1 && lsgn == -1))
  307.     {
  308.         lr.sign = -1;
  309.     }
  310.     Borrow(lr.vec);
  311.     r.Carry().ClearZeroVec().VecToStr();
  312.     lr.nsize = lr.vec.size();
  313.     return r;
  314. }
  315. //-
  316. const lnum lnum::operator-(const lnum &l) const
  317. {
  318.     lnum r;
  319.     if (l.num.vec != vector<int>(1,0))
  320.     {
  321.         r = *this + l.Negative();
  322.     }
  323.     else
  324.     {
  325.         r = *this;
  326.     }
  327.     return r;
  328. }
  329. //>>
  330. istream &operator>>(istream &is, lnum &l)
  331. {
  332.     string str;
  333.     (is >> str).get();
  334.     l = str;
  335.     return is;
  336. }
  337. //<<
  338. ostream &operator<<(ostream &os, const lnum &l)
  339. {
  340.     os << l.AttrToStr();
  341.     return os;
  342. }
复制代码


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

======================================================
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-scgixi2r.ntb --stdout=Microsoft-MIEngine-Out-luutv21b.4xa --stderr=Microsoft-MIEngine-Error-pjehcj35.j3v --pid=Microsoft-MIEngine-Pid-bxz2vs3q.lkd --dbgExe=D:\MinGW\bin\gdb.exe --interpreter=mi
input data:
0
123456789
a = 0
b = 123456789     
a + b = 123456789
a - b = -123456789
input data:      
123456789
0
a = 123456789
b = 0
a + b = 123456789
a - b = 123456789
input data:
-123456789
0
a = -123456789
b = 0
a + b = -123456789
a - b = -123456789
input data:
-123456789
0
a = -123456789
b = 0
a + b = -123456789
a - b = -123456789
input data:
-123456789
123456789
a = -123456789
b = 123456789
a + b = 0
a - b = -246913578
input data:
0
-123456789
a = 0
b = -123456789
a + b = -123456789
a - b = 123456789
input data:
999999999
555555555
a = 999999999
b = 555555555
a + b = 1555555554
a - b = 444444444


E:\Users\admin\Documents\VScode\Code>
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-12-29 13:02:13 | 显示全部楼层
加减完成

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.     struct attr
  13.     {
  14.         int sign = 1;          //符号;
  15.         size_t dpsize = 0;     //小数位;
  16.         size_t prec = 0;       //精度
  17.         size_t nsize = 1;      //有效位数
  18.         string str = "0";      //过渡字符串
  19.         vector<int> vec = {0}; //数组;
  20.     };
  21.     struct align
  22.     {
  23.         vector<int> first;

  24.         vector<int> second;
  25.     };

  26. private:
  27.     //小数精度;
  28.     static size_t precision;
  29.     //数据;
  30.     attr num;
  31.     //str to attr
  32.     const attr StrToAttr(const string &str) const;
  33.     //attr to str
  34.     const string AttrToStr() const;
  35.     //进1
  36.     lnum &Carry();
  37.     //借1
  38.     lnum Borrow();
  39.     //对齐
  40.     const align AlignVec(const vector<int> &m, const vector<int> &n) const;
  41.     //反转正负
  42.     const lnum Negative() const;
  43.     //clear zero vec
  44.     lnum &ClearZeroVec();
  45.     //vec to str
  46.     lnum &VecToStr();

  47. public:
  48.     lnum(const char *cstr = "0") : num(StrToAttr(cstr)){}
  49.     lnum(const string &str) : num(StrToAttr(str)) {}
  50.     lnum(const char c) : num(StrToAttr(string(1, c))) {}
  51.     lnum(const lnum &l) : num(l.num) {}
  52.     //------------------------------------------------------------------
  53.     //设置精度
  54.     static void SetPrecision(const size_t i);
  55.     //展示信息
  56.     void Showinfo() const;
  57.     //>
  58.     const bool operator>(const lnum &l) const;
  59.     //<
  60.     const bool operator<(const lnum &l) const;
  61.     //==
  62.     const bool operator==(const lnum &l) const;
  63.     //>=
  64.     const bool operator>=(const lnum &l) const;
  65.     //<=
  66.     const bool operator<=(const lnum &l) const;
  67.     //+
  68.     const lnum operator+(const lnum &l) const;
  69.     //-
  70.     const lnum operator-(const lnum &l) const;
  71.     //>>
  72.     friend istream &operator>>(istream &is, const lnum &l);
  73.     //<<
  74.     friend ostream &operator<<(ostream &os, const lnum &l);
  75. };
  76. size_t lnum::precision = 0;
  77. #endif
复制代码


lnum.cpp
  1. #include "E:\Users\admin\Documents\VScode\Code\My Class\shape.cpp\lnum\lnum.h"
  2. //str to attr
  3. const lnum::attr lnum::StrToAttr(const string &str) const
  4. {
  5.     attr n;
  6.     n.prec = precision;
  7.     n.str = str;
  8.     string &nstr = n.str;
  9.     size_t &ndps = n.dpsize, &npre = n.prec;
  10.     if (nstr[0] == '-')
  11.     {
  12.         nstr.erase(0, 1);
  13.     }
  14.     if (int(nstr.find('.')) != -1)
  15.     {
  16.         nstr.erase(nstr.find('.'), 1);
  17.     }
  18.     if (nstr == string(nstr.size(), '0'))
  19.     {
  20.         nstr.clear();
  21.         nstr.push_back('0');
  22.     }
  23.     else //if (nstr != string(nstr.size(), '0'))
  24.     {
  25.         size_t s = nstr.size(), i = 0;
  26.         if (str[0] == '-')
  27.         {
  28.             n.sign = -1;
  29.         }
  30.         if (int(str.find('.')) != -1)
  31.         {
  32.             ndps = str.size() - str.find('.') - 1;
  33.             if (nstr[0] == '0')
  34.             {

  35.                 for (; i < s; i++)
  36.                 {
  37.                     if (nstr[i] != '0')
  38.                     {
  39.                         break;
  40.                     }
  41.                 }
  42.                 if (i >= s - ndps)
  43.                 {
  44.                     nstr.erase(0, s - ndps - 1);
  45.                 }
  46.                 else if (i < s - ndps)
  47.                 {
  48.                     nstr.erase(0, i);
  49.                 }
  50.             }
  51.         }
  52.         else
  53.         {
  54.             if (nstr[0] == '0')
  55.             {
  56.                 for (i = 0; i < s; i++)
  57.                 {
  58.                     if (nstr[i] != '0')
  59.                     {
  60.                         break;
  61.                     }
  62.                 }
  63.                 nstr.erase(0, i);
  64.             }
  65.         }
  66.         if (npre > ndps)
  67.         {
  68.             nstr.insert(nstr.end(), npre - ndps, '0');
  69.         }
  70.         else if (npre < ndps)
  71.         {
  72.             nstr.erase(nstr.size() - (ndps - npre));
  73.             ndps = npre;
  74.         }
  75.         n.vec.clear();
  76.         for (char c : nstr)
  77.         {
  78.             n.vec.push_back(c - 48);
  79.         }
  80.         n.nsize = nstr.size();
  81.     }
  82.     return n;
  83. }
  84. //attr to str
  85. const string lnum::AttrToStr() const
  86. {
  87.     string t = num.str, &str = t;
  88.     const size_t &prec = num.prec, &dpsize = num.dpsize;
  89.     if (str.size() != 1 && prec != 0)
  90.     {
  91.         if (dpsize == prec)
  92.         {
  93.             str.insert(str.size() - prec, 1, '.');
  94.         }
  95.         else if (dpsize < prec && dpsize != 0)
  96.         {
  97.             str.erase(str.size() - (prec - dpsize));
  98.             str.insert(str.size() - dpsize, 1, '.');
  99.         }
  100.         else if (dpsize == 0)
  101.         {
  102.             str.erase(str.size() - prec);
  103.         }
  104.     }
  105.     if (num.sign == -1)
  106.     {
  107.         str.insert(0, 1, '-');
  108.     }
  109.     return str;
  110. }
  111. //进1
  112. lnum &lnum::Carry()
  113. {
  114.     vector<int> &v = num.vec;
  115.     v.insert(v.begin(), 1, 0);
  116.     size_t s = v.size();
  117.     for (size_t i = s - 1; i > 0; i--)
  118.     {
  119.         int t = v[i];
  120.         v[i] = t % 10;
  121.         v[i - 1] += t / 10;
  122.     }
  123.     return *this;
  124. }
  125. //借1
  126. lnum lnum::Borrow()
  127. {
  128.     vector<int> &v = num.vec;
  129.     size_t s = v.size();
  130.     for (size_t i = 1; i < s; i++)
  131.     {
  132.         v[i - 1] -= 1;
  133.         v[i] += 10;
  134.     }
  135.     return *this;
  136. }
  137. //对齐
  138. const lnum::align lnum::AlignVec(const vector<int> &m, const vector<int> &n) const
  139. {
  140.     align agn;
  141.     vector<int> &fst = agn.first, &sec = agn.second;
  142.     fst = m, sec = n;
  143.     size_t fsize = fst.size(), ssize = sec.size();
  144.     if (fsize < ssize)
  145.     {
  146.         fst.insert(fst.begin(), ssize - fsize, 0);
  147.     }
  148.     else if (fsize > ssize)
  149.     {
  150.         sec.insert(sec.begin(), fsize - ssize, 0);
  151.     }
  152.     return agn;
  153. }
  154. //反转正负
  155. const lnum lnum::Negative() const
  156. {
  157.     lnum r = *this;
  158.     r.num.sign = -num.sign;
  159.     return r;
  160. }
  161. //clear zero vec
  162. lnum &lnum::ClearZeroVec()
  163. {
  164.     const size_t &prec = num.prec;
  165.     vector<int> &v = num.vec;
  166.     if (v == vector<int>(v.size(), 0))
  167.     {
  168.         v.clear();
  169.         v.push_back(0);
  170.     }
  171.     else if (v[0] == 0)
  172.     {
  173.         size_t s = v.size(), i = 0;
  174.         if (prec != 0)
  175.         {

  176.             for (; i < s; i++)
  177.             {
  178.                 if (v[i] != 0)
  179.                 {
  180.                     break;
  181.                 }
  182.             }
  183.             if (i >= s - prec)
  184.             {
  185.                 v.erase(v.begin(), v.begin() + (s - prec - 1));
  186.             }
  187.             else if (i < s - prec)
  188.             {
  189.                 v.erase(v.begin(), v.begin() + i);
  190.             }
  191.         }
  192.         else
  193.         {
  194.             for (i = 0; i < s; i++)
  195.             {
  196.                 if (v[i] != 0)
  197.                 {
  198.                     break;
  199.                 }
  200.             }
  201.             v.erase(v.begin(), v.begin() + i);
  202.         }
  203.     }
  204.     return *this;
  205. }
  206. //vec to str
  207. lnum &lnum::VecToStr()
  208. {
  209.     num.str.clear();
  210.     for (int i : num.vec)
  211.     {
  212.         num.str.push_back(i + 48);
  213.     }
  214.     return *this;
  215. }
  216. //------------------------------------------------------------------------
  217. //设置精度
  218. void lnum::SetPrecision(const size_t i)
  219. {
  220.     lnum::precision = i;
  221. }
  222. //展示信息
  223. void lnum::Showinfo() const
  224. {
  225.     std::cout << "有效数位: ";
  226.     for (int i : num.vec)
  227.     {
  228.         std::cout << i << " ";
  229.     }
  230.     std::cout << std::endl;
  231.     std::cout << "正负符号: " << num.sign << "\n"
  232.               << "小数位数: " << num.dpsize << "\n"
  233.               << "小数精度: " << num.prec << "\n"
  234.               << "有效位数: " << num.nsize << std::endl;
  235. }
  236. //>
  237. const bool lnum::operator>(const lnum &l) const
  238. {
  239.     bool f = true;
  240.     align agn = AlignVec(num.vec, l.num.vec);
  241.     const vector<int> &fst = agn.first, &sec = agn.second;
  242.     if (num.sign < l.num.sign)
  243.     {
  244.         f = false;
  245.     }
  246.     if (num.sign == l.num.sign)
  247.     {
  248.         f = fst > sec;
  249.         if (num.sign == -1)
  250.         {
  251.             f = !f;
  252.         }
  253.     }
  254.     return f;
  255. }
  256. //<
  257. const bool lnum::operator<(const lnum &l) const
  258. {
  259.     bool f = true;
  260.     align agn = AlignVec(num.vec, l.num.vec);
  261.     const vector<int> &fst = agn.first, &sec = agn.second;
  262.     if (num.sign > l.num.sign)
  263.     {
  264.         f = false;
  265.     }
  266.     if (num.sign == l.num.sign)
  267.     {
  268.         f = fst < sec;
  269.         if (num.sign == -1)
  270.         {
  271.             f = !f;
  272.         }
  273.     }
  274.     return f;
  275. }
  276. //==
  277. const bool lnum::operator==(const lnum &l) const
  278. {
  279.     align agn = AlignVec(num.vec, l.num.vec);
  280.     const vector<int> &fst = agn.first, &sec = agn.second;
  281.     return fst == sec && num.sign == l.num.sign;
  282. }
  283. //>=
  284. const bool lnum::operator>=(const lnum &l) const
  285. {
  286.     return !(*this < l);
  287. }
  288. //<=
  289. const bool lnum::operator<=(const lnum &l) const
  290. {
  291.     return !(*this > l);
  292. }
  293. //+
  294. const lnum lnum::operator+(const lnum &l) const
  295. {

  296.     lnum r;
  297.     attr &lr = r.num;
  298.     const align &agn = AlignVec(num.vec, l.num.vec);
  299.     const int &tsgn = num.sign, &lsgn = l.num.sign;
  300.     const vector<int> &fst = agn.first, &sec = agn.second, &tvec = num.vec, &lvec = l.num.vec;
  301.     lr.prec = num.prec;
  302.     lr.dpsize = (num.dpsize >= l.num.dpsize ? num.dpsize : l.num.dpsize);
  303.     size_t s = (fst.size() <= sec.size() ? fst.size() : sec.size());
  304.     lr.vec = (fst >= sec ? fst : sec);
  305.     for (size_t i = 0; i < s; i++)
  306.     {
  307.         lr.vec[i] += (tsgn * lsgn) * ((sec <= fst ? sec : fst)[i]);
  308.     }
  309.     if ((fst > sec && tsgn < lsgn) || (fst < sec && tsgn > lsgn) || (tsgn == -1 && lsgn == -1))
  310.     {
  311.         lr.sign = -1;
  312.     }
  313.     if (tsgn*lsgn == -1)
  314.     {
  315.         r.Borrow();
  316.     }
  317.     r.Carry().ClearZeroVec().VecToStr();
  318.     lr.nsize = lr.vec.size();
  319.     return r;
  320. }
  321. //-
  322. const lnum lnum::operator-(const lnum &l) const
  323. {
  324.     lnum r;
  325.     if (l.num.vec != vector<int>(1,0))
  326.     {
  327.         r = *this + l.Negative();
  328.     }
  329.     else
  330.     {
  331.         r = *this;
  332.     }
  333.     return r;
  334. }
  335. //>>
  336. istream &operator>>(istream &is, lnum &l)
  337. {
  338.     string str;
  339.     (is >> str).get();
  340.     l = str;
  341.     return is;
  342. }
  343. //<<
  344. ostream &operator<<(ostream &os, const lnum &l)
  345. {
  346.     os << l.AttrToStr();
  347.     return os;
  348. }
复制代码


test.cpp
  1. #include "E:\Users\admin\Documents\VScode\Code\My Class\shape.cpp\lnum\lnum.cpp"
  2. #include <ctime>
  3. int main(int argc, char const *argv[])
  4. {
  5.     //lnum::SetPrecision();
  6.     lnum a, b;
  7.     int s = 0;
  8.     char m[5], n[5];
  9.     m[4] = '\0';
  10.     n[4] = '\0';
  11.     srand(time(NULL));
  12.     while (s != 10)
  13.     {
  14.         for (size_t i = 0; i < 4; i++)
  15.         {
  16.             m[i] = 48+(rand() % 9);
  17.             n[i] = 48 + (rand() % 9);
  18.         }
  19.         a = m;
  20.         b = n;
  21.         std::cout << "a = " << a << "\n"
  22.                   << "b = " << b << "\n"
  23.                   << "a + b = " << (a + b) << "\n"
  24.                   << "a - b = " << (a - b) << std::boolalpha << "\n"
  25.                   << "a >  b: " << (a > b) << "\n"
  26.                   << "a == b: " << (a == b) << "\n"
  27.                   << "a <  b: " << (a < b)<<std::endl;
  28.         s++;
  29.     }
  30.     return 0;
  31. }
复制代码

===================================================
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-eboo5i2a.scs --stdout=Microsoft-MIEngine-Out-r4tarar5.3rq --stderr=Microsoft-MIEngine-Error-qhegr14x.fpe --pid=Microsoft-MIEngine-Pid-fmhxlme1.czb --dbgExe=D:\MinGW\bin\gdb.exe --interpreter=mi
a = 5332     
b = 401      
a + b = 5733
a - b = 4931
a >  b: true
a == b: false
a <  b: false
a = 58      
b = 664      
a + b = 722  
a - b = -606
a >  b: false
a == b: false
a <  b: true
a = 4535
b = 4804
a + b = 9339
a - b = -269
a >  b: false
a == b: false
a <  b: true
a = 3751
b = 580
a + b = 4331
a - b = 3171
a >  b: true
a == b: false
a <  b: false
a = 1725
b = 8817
a + b = 10542
a - b = -7092
a >  b: false
a == b: false
a <  b: true
a = 6707
b = 2004
a + b = 8711
a - b = 4703
a >  b: true
a == b: false
a <  b: false
a = 1604
b = 626
a + b = 2230
a - b = 978
a >  b: true
a == b: false
a <  b: false
a = 6284
b = 4865
a + b = 11149
a - b = 1419
a >  b: true
a == b: false
a <  b: false
a = 1810
b = 3604
a + b = 5414
a - b = -1794
a >  b: false
a == b: false
a <  b: true
a = 4671
b = 8577
a + b = 13248
a - b = -3906
a >  b: false
a == b: false
a <  b: true


E:\Users\admin\Documents\VScode\Code>
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-12-29 18:32:34 | 显示全部楼层
  1. num.h

  2. #ifndef LNUM_H
  3. #define LNUM_H
  4. #include <iostream>
  5. #include <string>
  6. #include <vector>
  7. using std::istream;
  8. using std::ostream;
  9. using std::string;
  10. using std::vector;
  11. class lnum
  12. {
  13.     struct attr
  14.     {
  15.         int sign = 1;          //符号;
  16.         size_t dpsize = 0;     //小数位;
  17.         size_t prec = 0;       //精度
  18.         size_t nsize = 1;      //有效位数
  19.         string str = "0";      //过渡字符串
  20.         vector<int> vec = {0}; //数组;
  21.     };
  22.     struct align
  23.     {
  24.         vector<int> first;
  25.         vector<int> second;
  26.     };

  27. private:
  28.     //小数精度;
  29.     static size_t precision;
  30.     //数据;
  31.     attr num;
  32.     //str to attr
  33.     const attr StrToAttr(const string &str) const;
  34.     //attr to str
  35.     const string AttrToStr() const;
  36.     //进1
  37.     lnum &Carry();
  38.     //借1
  39.     lnum Borrow();
  40.     //对齐
  41.     const align AlignVec(const vector<int> &m, const vector<int> &n) const;
  42.     //clear zero vec
  43.     lnum &ClearZeroVec();
  44.     //vec to str
  45.     lnum &VecToStr();

  46. public:
  47.     lnum(const char *cstr = "0") : num(StrToAttr(cstr)){}
  48.     lnum(const string &str) : num(StrToAttr(str)) {}
  49.     lnum(const char c) : num(StrToAttr(string(1, c))) {}
  50.     lnum(const lnum &l) : num(l.num) {}
  51.     //------------------------------------------------------------------
  52.     //设置精度
  53.     static void SetPrecision(const size_t i);
  54.     //展示信息
  55.     void Showinfo() const;
  56.     //>
  57.     const bool operator>(const lnum &l) const;
  58.     //<
  59.     const bool operator<(const lnum &l) const;
  60.     //==
  61.     const bool operator==(const lnum &l) const;
  62.     //>=
  63.     const bool operator>=(const lnum &l) const;
  64.     //<=
  65.     const bool operator<=(const lnum &l) const;
  66.     //+
  67.     const lnum operator+(const lnum &l) const;
  68.     //-
  69.     const lnum operator-(const lnum &l) const;
  70.     const lnum operator-() const;
  71.     //>>
  72.     friend istream &operator>>(istream &is, const lnum &l);
  73.     //<<
  74.     friend ostream &operator<<(ostream &os, const lnum &l);
  75. };
  76. size_t lnum::precision = 0;
  77. #endif

  78. lnum.cpp

  79. #include "E:\Users\admin\Documents\VScode\Code\My Class\shape.cpp\lnum\lnum.h"
  80. //str to attr
  81. const lnum::attr lnum::StrToAttr(const string &str) const
  82. {
  83.     attr n;
  84.     n.prec = precision;
  85.     n.str = str;
  86.     string &nstr = n.str;
  87.     size_t &ndps = n.dpsize, &npre = n.prec;
  88.     if (nstr[0] == '-')
  89.     {
  90.         nstr.erase(0, 1);
  91.     }
  92.     if (int(nstr.find('.')) != -1)
  93.     {
  94.         nstr.erase(nstr.find('.'), 1);
  95.     }
  96.     if (nstr == string(nstr.size(), '0'))
  97.     {
  98.         nstr.clear();
  99.         nstr.push_back('0');
  100.     }
  101.     else //if (nstr != string(nstr.size(), '0'))
  102.     {
  103.         size_t s = nstr.size(), i = 0;
  104.         if (str[0] == '-')
  105.         {
  106.             n.sign = -1;
  107.         }
  108.         if (int(str.find('.')) != -1)
  109.         {
  110.             ndps = str.size() - str.find('.') - 1;
  111.             if (nstr[0] == '0')
  112.             {

  113.                 for (; i < s; i++)
  114.                 {
  115.                     if (nstr[i] != '0')
  116.                     {
  117.                         break;
  118.                     }
  119.                 }
  120.                 if (i >= s - ndps)
  121.                 {
  122.                     nstr.erase(0, s - ndps - 1);
  123.                 }
  124.                 else if (i < s - ndps)
  125.                 {
  126.                     nstr.erase(0, i);
  127.                 }
  128.             }
  129.         }
  130.         else
  131.         {
  132.             if (nstr[0] == '0')
  133.             {
  134.                 for (i = 0; i < s; i++)
  135.                 {
  136.                     if (nstr[i] != '0')
  137.                     {
  138.                         break;
  139.                     }
  140.                 }
  141.                 nstr.erase(0, i);
  142.             }
  143.         }
  144.         if (npre > ndps)
  145.         {
  146.             nstr.insert(nstr.end(), npre - ndps, '0');
  147.         }
  148.         else if (npre < ndps)
  149.         {
  150.             nstr.erase(nstr.size() - (ndps - npre));
  151.             ndps = npre;
  152.         }
  153.         n.vec.clear();
  154.         for (char c : nstr)
  155.         {
  156.             n.vec.push_back(c - 48);
  157.         }
  158.         n.nsize = nstr.size();
  159.     }
  160.     return n;
  161. }
  162. //attr to str
  163. const string lnum::AttrToStr() const
  164. {
  165.     string t = num.str, &str = t;
  166.     const size_t &prec = num.prec, &dpsize = num.dpsize;
  167.     if (str.size() != 1 && prec != 0)
  168.     {
  169.         if (dpsize == prec)
  170.         {
  171.             str.insert(str.size() - prec, 1, '.');
  172.         }
  173.         else if (dpsize < prec && dpsize != 0)
  174.         {
  175.             str.erase(str.size() - (prec - dpsize));
  176.             str.insert(str.size() - dpsize, 1, '.');
  177.         }
  178.         else if (dpsize == 0)
  179.         {
  180.             str.erase(str.size() - prec);
  181.         }
  182.     }
  183.     if (num.sign == -1)
  184.     {
  185.         str.insert(0, 1, '-');
  186.     }
  187.     return str;
  188. }
  189. //进1
  190. lnum &lnum::Carry()
  191. {
  192.     vector<int> &v = num.vec;
  193.     v.insert(v.begin(), 1, 0);
  194.     size_t s = v.size();
  195.     for (size_t i = s - 1; i > 0; i--)
  196.     {
  197.         int t = v[i];
  198.         v[i] = t % 10;
  199.         v[i - 1] += t / 10;
  200.     }
  201.     return *this;
  202. }
  203. //借1
  204. lnum lnum::Borrow()
  205. {
  206.     vector<int> &v = num.vec;
  207.     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.     return *this;
  214. }
  215. //对齐
  216. const lnum::align lnum::AlignVec(const vector<int> &m, const vector<int> &n) const
  217. {
  218.     align agn;
  219.     vector<int> &fst = agn.first, &sec = agn.second;
  220.     fst = m, sec = n;
  221.     size_t fsize = fst.size(), ssize = sec.size();
  222.     if (fsize < ssize)
  223.     {
  224.         fst.insert(fst.begin(), ssize - fsize, 0);
  225.     }
  226.     else if (fsize > ssize)
  227.     {
  228.         sec.insert(sec.begin(), fsize - ssize, 0);
  229.     }
  230.     return agn;
  231. }
  232. //clear zero vec
  233. lnum &lnum::ClearZeroVec()
  234. {
  235.     const size_t &prec = num.prec;
  236.     vector<int> &v = num.vec;
  237.     if (v == vector<int>(v.size(), 0))
  238.     {
  239.         v.clear();
  240.         v.push_back(0);
  241.     }
  242.     else if (v[0] == 0)
  243.     {
  244.         size_t s = v.size(), i = 0;
  245.         if (prec != 0)
  246.         {

  247.             for (; i < s; i++)
  248.             {
  249.                 if (v[i] != 0)
  250.                 {
  251.                     break;
  252.                 }
  253.             }
  254.             if (i >= s - prec)
  255.             {
  256.                 v.erase(v.begin(), v.begin() + (s - prec - 1));
  257.             }
  258.             else if (i < s - prec)
  259.             {
  260.                 v.erase(v.begin(), v.begin() + i);
  261.             }
  262.         }
  263.         else
  264.         {
  265.             for (i = 0; i < s; i++)
  266.             {
  267.                 if (v[i] != 0)
  268.                 {
  269.                     break;
  270.                 }
  271.             }
  272.             v.erase(v.begin(), v.begin() + i);
  273.         }
  274.     }
  275.     return *this;
  276. }
  277. //vec to str
  278. lnum &lnum::VecToStr()
  279. {
  280.     num.str.clear();
  281.     for (int i : num.vec)
  282.     {
  283.         num.str.push_back(i + 48);
  284.     }
  285.     return *this;
  286. }
  287. //------------------------------------------------------------------------
  288. //设置精度
  289. void lnum::SetPrecision(const size_t i)
  290. {
  291.     lnum::precision = i;
  292. }
  293. //展示信息
  294. void lnum::Showinfo() const
  295. {
  296.     std::cout << "有效数位: ";
  297.     for (int i : num.vec)
  298.     {
  299.         std::cout << i << " ";
  300.     }
  301.     std::cout << std::endl;
  302.     std::cout << "正负符号: " << num.sign << "\n"
  303.               << "小数位数: " << num.dpsize << "\n"
  304.               << "小数精度: " << num.prec << "\n"
  305.               << "有效位数: " << num.nsize << std::endl;
  306. }
  307. //>
  308. const bool lnum::operator>(const lnum &l) const
  309. {
  310.     bool f = true;
  311.     align agn = AlignVec(num.vec, l.num.vec);
  312.     const vector<int> &fst = agn.first, &sec = agn.second;
  313.     if (num.sign < l.num.sign)
  314.     {
  315.         f = false;
  316.     }
  317.     if (num.sign == l.num.sign)
  318.     {
  319.         f = fst > sec;
  320.         if (num.sign == -1)
  321.         {
  322.             f = !f;
  323.         }
  324.     }
  325.     return f;
  326. }
  327. //<
  328. const bool lnum::operator<(const lnum &l) const
  329. {
  330.     bool f = true;
  331.     align agn = AlignVec(num.vec, l.num.vec);
  332.     const vector<int> &fst = agn.first, &sec = agn.second;
  333.     if (num.sign > l.num.sign)
  334.     {
  335.         f = false;
  336.     }
  337.     if (num.sign == l.num.sign)
  338.     {
  339.         f = fst < sec;
  340.         if (num.sign == -1)
  341.         {
  342.             f = !f;
  343.         }
  344.     }
  345.     return f;
  346. }
  347. //==
  348. const bool lnum::operator==(const lnum &l) const
  349. {
  350.     align agn = AlignVec(num.vec, l.num.vec);
  351.     const vector<int> &fst = agn.first, &sec = agn.second;
  352.     return fst == sec && num.sign == l.num.sign;
  353. }
  354. //>=
  355. const bool lnum::operator>=(const lnum &l) const
  356. {
  357.     return !(*this < l);
  358. }
  359. //<=
  360. const bool lnum::operator<=(const lnum &l) const
  361. {
  362.     return !(*this > l);
  363. }
  364. //+
  365. const lnum lnum::operator+(const lnum &l) const
  366. {

  367.     lnum r;
  368.     attr &lr = r.num;
  369.     const align &agn = AlignVec(num.vec, l.num.vec);
  370.     const int &tsgn = num.sign, &lsgn = l.num.sign;
  371.     const vector<int> &fst = agn.first, &sec = agn.second, &tvec = num.vec, &lvec = l.num.vec;
  372.     lr.prec = num.prec;
  373.     lr.dpsize = (num.dpsize >= l.num.dpsize ? num.dpsize : l.num.dpsize);
  374.     size_t s = (fst.size() <= sec.size() ? fst.size() : sec.size());
  375.     lr.vec = (fst >= sec ? fst : sec);
  376.     for (size_t i = 0; i < s; i++)
  377.     {
  378.         lr.vec[i] += (tsgn * lsgn) * ((sec <= fst ? sec : fst)[i]);
  379.     }
  380.     if ((fst > sec && tsgn < lsgn) || (fst < sec && tsgn > lsgn) || (tsgn == -1 && lsgn == -1))
  381.     {
  382.         lr.sign = -1;
  383.     }
  384.     if (tsgn*lsgn == -1)
  385.     {
  386.         r.Borrow();
  387.     }
  388.     r.Carry().ClearZeroVec().VecToStr();
  389.     lr.nsize = lr.vec.size();
  390.     return r;
  391. }
  392. //符号取反
  393. const lnum lnum::operator-() const
  394. {
  395.     const vector<int> &tvec = num.vec;
  396.     lnum r = *this;
  397.     if (tvec != vector<int>(tvec.size(), 0))
  398.     {
  399.         r.num.sign = -num.sign;
  400.     }
  401.     return r;
  402. }
  403. //-
  404. const lnum lnum::operator-(const lnum &l) const
  405. {
  406.     lnum r;
  407.     if (l.num.vec != vector<int>(1,0))
  408.     {
  409.         r = *this + (-l);
  410.     }
  411.     else
  412.     {
  413.         r = *this;
  414.     }
  415.     return r;
  416. }
  417. //>>
  418. istream &operator>>(istream &is, lnum &l)
  419. {
  420.     string str;
  421.     (is >> str).get();
  422.     l = str;
  423.     return is;
  424. }
  425. //<<
  426. ostream &operator<<(ostream &os, const lnum &l)
  427. {
  428.     os << l.AttrToStr();
  429.     return os;
  430. }


  431. test.cpp

  432. #include "E:\Users\admin\Documents\VScode\Code\My Class\shape.cpp\lnum\lnum.cpp"
  433. #include <ctime>
  434. #include <cmath>
  435. int main(int argc, char const *argv[])
  436. {
  437.     //lnum::SetPrecision();
  438.     lnum a, b;
  439.     int s = 0;
  440.     char m[5], n[5];
  441.     m[4] = '\0';
  442.     n[4] = '\0';
  443.     srand(time(NULL));
  444.     while (s != 10)
  445.     {
  446.         for (size_t i = 0; i < 4; i++)
  447.         {
  448.             m[i] = (48+(rand() % 9));
  449.             n[i] = 48 + (rand() % 9);
  450.             if (m[i] % 3 == 0)
  451.             {
  452.                 m[0] = '-';
  453.             }
  454.             if (n[2] % 2== 0)
  455.             {
  456.                 n[0] = '-';
  457.             }
  458.         }
  459.         a = m;
  460.         b = n;
  461.         std::cout << "a = " << a << "  "
  462.                   << "b = " << b << "\n"
  463.                   << a << " +  " << b << " = " << (a + b) << "\n"
  464.                   << a << " -  " << b << " = " << (a - b) << std::boolalpha << "\n"
  465.                   << a << " >  " << b << " : " << (a > b) << "\n"
  466.                   << a << " == " << b << " : " << (a == b) << "\n"
  467.                   << a << " <  " << b << " : " << (a < b) << "\n"
  468.                   << std::endl;
  469.         s++;
  470.     }
  471.     return 0;
  472. }
复制代码

========================================================
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-ul1mqoep.0q0 --stdout=Microsoft-MIEngine-Out-unmtncle.kyu --stderr=Microsoft-MIEngine-Error-5vrplf5c.qy3 --pid=Microsoft-MIEngine-Pid-ofqfqron.oyu --dbgExe=D:\MinGW\bin\gdb.exe --interpreter=mi
a = -862  b = -133
-862 +  -133 = -995
-862 -  -133 = -729
-862 >  -133 : false
-862 == -133 : false
-862 <  -133 : true

a = -317  b = 4114  
-317 +  4114 = 3797
-317 -  4114 = -4431
-317 >  4114 : false
-317 == 4114 : false
-317 <  4114 : true

a = -766  b = 4011
-766 +  4011 = 3245
-766 -  4011 = -4777
-766 >  4011 : false
-766 == 4011 : false
-766 <  4011 : true

a = -533  b = -286
-533 +  -286 = -819
-533 -  -286 = -247
-533 >  -286 : false
-533 == -286 : false
-533 <  -286 : true

a = -28  b = -830
-28 +  -830 = -858
-28 -  -830 = 802
-28 >  -830 : true
-28 == -830 : false
-28 <  -830 : false

a = 7858  b = 2216
7858 +  2216 = 10074
7858 -  2216 = 5642
7858 >  2216 : true
7858 == 2216 : false
7858 <  2216 : false

a = -722  b = -20
-722 +  -20 = -742
-722 -  -20 = -702
-722 >  -20 : false
-722 == -20 : false
-722 <  -20 : true

a = -670  b = -360
-670 +  -360 = -1030
-670 -  -360 = -310
-670 >  -360 : false
-670 == -360 : false
-670 <  -360 : true

a = -231  b = -226
-231 +  -226 = -457
-231 -  -226 = -5
-231 >  -226 : false
-231 == -226 : false
-231 <  -226 : true

a = -782  b = -116
-782 +  -116 = -898
-782 -  -116 = -666
-782 >  -116 : false
-782 == -116 : false
-782 <  -116 : true



E:\Users\admin\Documents\VScode\Code>
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-12-29 20:08:49 | 显示全部楼层
本帖最后由 bin554385863 于 2019-12-29 20:26 编辑

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.     struct attr
  13.     {
  14.         int sign = 1;          //符号;
  15.         size_t dpsize = 0;     //小数位;
  16.         size_t prec = 0;       //精度
  17.         size_t nsize = 1;      //有效位数
  18.         string str = "0";      //过渡字符串
  19.         vector<int> vec = {0}; //数组;
  20.     };
  21.     struct align
  22.     {
  23.         vector<int> first;
  24.         vector<int> second;
  25.     };

  26. private:
  27.     //小数精度;
  28.     static size_t precision;
  29.     //数据;
  30.     attr num;
  31.     //str to attr
  32.     const attr StrToAttr(const string &str) const;
  33.     //attr to str
  34.     const string AttrToStr() const;
  35.     //进1
  36.     lnum &Carry();
  37.     //借1
  38.     lnum Borrow();
  39.     //对齐
  40.     const align AlignVec(const vector<int> &m, const vector<int> &n) const;
  41.     //clear zero vec
  42.     lnum &ClearZeroVec();
  43.     //vec to str
  44.     lnum &VecToStr();
  45.    
  46. public:
  47.     lnum(const char *cstr = "0") : num(StrToAttr(cstr)){}
  48.     lnum(const string &str) : num(StrToAttr(str)){}
  49.     lnum(const lnum &l) : num(l.num) {}
  50.     //------------------------------------------------------------------
  51.     //设置精度
  52.     static void SetPrecision(const size_t i);
  53.     //展示信息
  54.     void Showinfo() const;
  55.     //>
  56.     const bool operator>(const lnum &l) const;
  57.     //<
  58.     const bool operator<(const lnum &l) const;
  59.     //==
  60.     const bool operator==(const lnum &l) const;
  61.     //>=
  62.     const bool operator>=(const lnum &l) const;
  63.     //<=
  64.     const bool operator<=(const lnum &l) const;
  65.     //+
  66.     const lnum operator+(const lnum &l) const;
  67.     //-
  68.     const lnum operator-(const lnum &l) const;
  69.     const lnum operator-() const;
  70.     //+=
  71.     const lnum &operator+=(const lnum &l);
  72.     //++
  73.     const lnum &operator++();
  74.     //-=
  75.     const lnum &operator-=(const lnum &l);
  76.     //--
  77.     const lnum &operator--();
  78.     //odject++
  79.     friend const lnum &operator++(lnum &l, const int i);
  80.     //object--
  81.     friend const lnum &operator--(lnum &l, const int i);
  82.     //>>
  83.     friend istream &operator>>(istream &is, const lnum &l);
  84.     //<<
  85.     friend ostream &operator<<(ostream &os, const lnum &l);
  86. };
  87. size_t lnum::precision = 0;
  88. #endif
复制代码


lnum.cpp
  1. #include "E:\Users\admin\Documents\VScode\Code\My Class\shape.cpp\lnum\lnum.h"
  2. //str to attr
  3. const lnum::attr lnum::StrToAttr(const string &str) const
  4. {
  5.     attr n;
  6.     n.prec = precision;
  7.     n.str = str;
  8.     string &nstr = n.str;
  9.     size_t &ndps = n.dpsize, &npre = n.prec;
  10.     if (nstr[0] == '-')
  11.     {
  12.         nstr.erase(0, 1);
  13.     }
  14.     if (int(nstr.find('.')) != -1)
  15.     {
  16.         nstr.erase(nstr.find('.'), 1);
  17.     }
  18.     if (nstr == string(nstr.size(), '0'))
  19.     {
  20.         nstr.clear();
  21.         nstr.push_back('0');
  22.     }
  23.     else //if (nstr != string(nstr.size(), '0'))
  24.     {
  25.         size_t s = nstr.size(), i = 0;
  26.         if (str[0] == '-')
  27.         {
  28.             n.sign = -1;
  29.         }
  30.         if (int(str.find('.')) != -1)
  31.         {
  32.             ndps = str.size() - str.find('.') - 1;
  33.             if (nstr[0] == '0')
  34.             {

  35.                 for (; i < s; i++)
  36.                 {
  37.                     if (nstr[i] != '0')
  38.                     {
  39.                         break;
  40.                     }
  41.                 }
  42.                 if (i >= s - ndps)
  43.                 {
  44.                     nstr.erase(0, s - ndps - 1);
  45.                 }
  46.                 else if (i < s - ndps)
  47.                 {
  48.                     nstr.erase(0, i);
  49.                 }
  50.             }
  51.         }
  52.         else
  53.         {
  54.             if (nstr[0] == '0')
  55.             {
  56.                 for (i = 0; i < s; i++)
  57.                 {
  58.                     if (nstr[i] != '0')
  59.                     {
  60.                         break;
  61.                     }
  62.                 }
  63.                 nstr.erase(0, i);
  64.             }
  65.         }
  66.         if (npre > ndps)
  67.         {
  68.             nstr.insert(nstr.end(), npre - ndps, '0');
  69.         }
  70.         else if (npre < ndps)
  71.         {
  72.             nstr.erase(nstr.size() - (ndps - npre));
  73.             ndps = npre;
  74.         }
  75.         n.vec.clear();
  76.         for (char c : nstr)
  77.         {
  78.             n.vec.push_back(c - 48);
  79.         }
  80.         n.nsize = nstr.size();
  81.     }
  82.     return n;
  83. }
  84. //attr to str
  85. const string lnum::AttrToStr() const
  86. {
  87.     string t = num.str, &str = t;
  88.     const size_t &prec = num.prec, &dpsize = num.dpsize;
  89.     if (str.size() != 1 && prec != 0)
  90.     {
  91.         if (dpsize == prec)
  92.         {
  93.             str.insert(str.size() - prec, 1, '.');
  94.         }
  95.         else if (dpsize < prec && dpsize != 0)
  96.         {
  97.             str.erase(str.size() - (prec - dpsize));
  98.             str.insert(str.size() - dpsize, 1, '.');
  99.         }
  100.         else if (dpsize == 0)
  101.         {
  102.             str.erase(str.size() - prec);
  103.         }
  104.     }
  105.     if (num.sign == -1)
  106.     {
  107.         str.insert(0, 1, '-');
  108.     }
  109.     return str;
  110. }
  111. //进1
  112. lnum &lnum::Carry()
  113. {
  114.     vector<int> &v = num.vec;
  115.     v.insert(v.begin(), 1, 0);
  116.     size_t s = v.size();
  117.     for (size_t i = s - 1; i > 0; i--)
  118.     {
  119.         int t = v[i];
  120.         v[i] = t % 10;
  121.         v[i - 1] += t / 10;
  122.     }
  123.     return *this;
  124. }
  125. //借1
  126. lnum lnum::Borrow()
  127. {
  128.     vector<int> &v = num.vec;
  129.     size_t s = v.size();
  130.     for (size_t i = 1; i < s; i++)
  131.     {
  132.         v[i - 1] -= 1;
  133.         v[i] += 10;
  134.     }
  135.     return *this;
  136. }
  137. //对齐
  138. const lnum::align lnum::AlignVec(const vector<int> &m, const vector<int> &n) const
  139. {
  140.     align agn;
  141.     vector<int> &fst = agn.first, &sec = agn.second;
  142.     fst = m, sec = n;
  143.     size_t fsize = fst.size(), ssize = sec.size();
  144.     if (fsize < ssize)
  145.     {
  146.         fst.insert(fst.begin(), ssize - fsize, 0);
  147.     }
  148.     else if (fsize > ssize)
  149.     {
  150.         sec.insert(sec.begin(), fsize - ssize, 0);
  151.     }
  152.     return agn;
  153. }
  154. //clear zero vec
  155. lnum &lnum::ClearZeroVec()
  156. {
  157.     const size_t &prec = num.prec;
  158.     vector<int> &v = num.vec;
  159.     if (v == vector<int>(v.size(), 0))
  160.     {
  161.         v.clear();
  162.         v.push_back(0);
  163.     }
  164.     else if (v[0] == 0)
  165.     {
  166.         size_t s = v.size(), i = 0;
  167.         if (prec != 0)
  168.         {

  169.             for (; i < s; i++)
  170.             {
  171.                 if (v[i] != 0)
  172.                 {
  173.                     break;
  174.                 }
  175.             }
  176.             if (i >= s - prec)
  177.             {
  178.                 v.erase(v.begin(), v.begin() + (s - prec - 1));
  179.             }
  180.             else if (i < s - prec)
  181.             {
  182.                 v.erase(v.begin(), v.begin() + i);
  183.             }
  184.         }
  185.         else
  186.         {
  187.             for (i = 0; i < s; i++)
  188.             {
  189.                 if (v[i] != 0)
  190.                 {
  191.                     break;
  192.                 }
  193.             }
  194.             v.erase(v.begin(), v.begin() + i);
  195.         }
  196.     }
  197.     return *this;
  198. }
  199. //vec to str
  200. lnum &lnum::VecToStr()
  201. {
  202.     num.str.clear();
  203.     for (int i : num.vec)
  204.     {
  205.         num.str.push_back(i + 48);
  206.     }
  207.     return *this;
  208. }
  209. //------------------------------------------------------------------------
  210. //设置精度
  211. void lnum::SetPrecision(const size_t i)
  212. {
  213.     lnum::precision = i;
  214. }
  215. //展示信息
  216. void lnum::Showinfo() const
  217. {
  218.     std::cout << "有效数位: ";
  219.     for (int i : num.vec)
  220.     {
  221.         std::cout << i << " ";
  222.     }
  223.     std::cout << std::endl;
  224.     std::cout << "正负符号: " << num.sign << "\n"
  225.               << "小数位数: " << num.dpsize << "\n"
  226.               << "小数精度: " << num.prec << "\n"
  227.               << "有效位数: " << num.nsize << std::endl;
  228. }
  229. //>
  230. const bool lnum::operator>(const lnum &l) const
  231. {
  232.     bool f = true;
  233.     align agn = AlignVec(num.vec, l.num.vec);
  234.     const vector<int> &fst = agn.first, &sec = agn.second;
  235.     if (num.sign < l.num.sign)
  236.     {
  237.         f = false;
  238.     }
  239.     if (num.sign == l.num.sign)
  240.     {
  241.         f = fst > sec;
  242.         if (num.sign == -1)
  243.         {
  244.             f = !f;
  245.         }
  246.     }
  247.     return f;
  248. }
  249. //<
  250. const bool lnum::operator<(const lnum &l) const
  251. {
  252.     bool f = true;
  253.     align agn = AlignVec(num.vec, l.num.vec);
  254.     const vector<int> &fst = agn.first, &sec = agn.second;
  255.     if (num.sign > l.num.sign)
  256.     {
  257.         f = false;
  258.     }
  259.     if (num.sign == l.num.sign)
  260.     {
  261.         f = fst < sec;
  262.         if (num.sign == -1)
  263.         {
  264.             f = !f;
  265.         }
  266.     }
  267.     return f;
  268. }
  269. //==
  270. const bool lnum::operator==(const lnum &l) const
  271. {
  272.     align agn = AlignVec(num.vec, l.num.vec);
  273.     const vector<int> &fst = agn.first, &sec = agn.second;
  274.     return fst == sec && num.sign == l.num.sign;
  275. }
  276. //>=
  277. const bool lnum::operator>=(const lnum &l) const
  278. {
  279.     return !(*this < l);
  280. }
  281. //<=
  282. const bool lnum::operator<=(const lnum &l) const
  283. {
  284.     return !(*this > l);
  285. }
  286. //+
  287. const lnum lnum::operator+(const lnum &l) const
  288. {

  289.     lnum r;
  290.     attr &lr = r.num;
  291.     const align &agn = AlignVec(num.vec, l.num.vec);
  292.     const int &tsgn = num.sign, &lsgn = l.num.sign;
  293.     const vector<int> &fst = agn.first, &sec = agn.second, &tvec = num.vec, &lvec = l.num.vec;
  294.     lr.prec = num.prec;
  295.     lr.dpsize = (num.dpsize >= l.num.dpsize ? num.dpsize : l.num.dpsize);
  296.     size_t s = (fst.size() <= sec.size() ? fst.size() : sec.size());
  297.     lr.vec = (fst >= sec ? fst : sec);
  298.     for (size_t i = 0; i < s; i++)
  299.     {
  300.         lr.vec[i] += (tsgn * lsgn) * ((sec <= fst ? sec : fst)[i]);
  301.     }
  302.     if ((fst > sec && tsgn < lsgn) || (fst < sec && tsgn > lsgn) || (tsgn == -1 && lsgn == -1))
  303.     {
  304.         lr.sign = -1;
  305.     }
  306.     if (tsgn*lsgn == -1)
  307.     {
  308.         r.Borrow();
  309.     }
  310.     r.Carry().ClearZeroVec().VecToStr();
  311.     lr.nsize = lr.vec.size();
  312.     return r;
  313. }
  314. //符号取反
  315. const lnum lnum::operator-() const
  316. {
  317.     const vector<int> &tvec = num.vec;
  318.     lnum r = *this;
  319.     if (tvec != vector<int>(tvec.size(), 0))
  320.     {
  321.         r.num.sign = -num.sign;
  322.     }
  323.     return r;
  324. }
  325. //-
  326. const lnum lnum::operator-(const lnum &l) const
  327. {
  328.     lnum r;
  329.     if (l.num.vec != vector<int>(1,0))
  330.     {
  331.         r = *this + (-l);
  332.     }
  333.     else
  334.     {
  335.         r = *this;
  336.     }
  337.     return r;
  338. }
  339. //+=
  340. const lnum &lnum::operator+=(const lnum &l)
  341. {
  342.     *this = *this + l;
  343.     return *this;
  344. }
  345. //前置++
  346. const lnum &lnum::operator++()
  347. {
  348.     return *this += "1";
  349. }
  350. //-=
  351. const lnum &lnum::operator-=(const lnum &l)
  352. {
  353.     *this = *this - l;
  354.     return *this;
  355. }
  356. //前置--
  357. const lnum &lnum::operator--()
  358. {
  359.     return *this -= "1";
  360. }
  361. //后置++
  362. const lnum &operator++(lnum &l, const int i)
  363. {
  364.     return ++l;
  365. }
  366. //后置--
  367. const lnum &operator--(lnum &l, const int i)
  368. {
  369.     return --l;
  370. }
  371. //>>
  372. istream &operator>>(istream &is, lnum &l)
  373. {
  374.     string str;
  375.     (is >> str).get();
  376.     l = str;
  377.     return is;
  378. }
  379. //<<
  380. ostream &operator<<(ostream &os, const lnum &l)
  381. {
  382.     os << l.AttrToStr();
  383.     return os;
  384. }
复制代码


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

============================================
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-ftgy2k0d.itp --stdout=Microsoft-MIEngine-Out-ypcddczr.vhp --stderr=Microsoft-MIEngine-Error-aa1im5qa.s4b --pid=Microsoft-MIEngine-Pid-hnjifgnz.bpc --dbgExe=D:\MinGW\bin\gdb.exe --interpreter=mi
第0组
-3310042360415.7776 - -524736183.452446 = -3309517624232.325154
-3310042360415.7776 + -524736183.452446 = -3310567096599.230046

-3310042360415.7776 >  -524736183.452446: false

-3310042360415.7776 == -524736183.452446: false

-3310042360415.7776 <  -524736183.452446: true

-3310042360415.7776 >= -524736183.452446: false

-3310042360415.7776 <= -524736183.452446: true
------------------------------------------------

第1组
28831215742566646.3 - 5015516270.023648 = 28831210727050376.276352
28831215742566646.3 + 5015516270.023648 = 28831220758082916.323648

28831215742566646.3 >  5015516270.023648: true

28831215742566646.3 == 5015516270.023648: false

28831215742566646.3 <  5015516270.023648: false

28831215742566646.3 >= 5015516270.023648: true

28831215742566646.3 <= 5015516270.023648: false
------------------------------------------------

第2组
8060338.678225 - -84420108108320.115 = 84420116168658.793225
8060338.678225 + -84420108108320.115 = -84420100047981.436775

8060338.678225 >  -84420108108320.115: true

8060338.678225 == -84420108108320.115: false

8060338.678225 <  -84420108108320.115: false

8060338.678225 >= -84420108108320.115: true

8060338.678225 <= -84420108108320.115: false
------------------------------------------------

第3组
-571270373.546517 - 608762417821245.015 = -608762989091618.561517
-571270373.546517 + 608762417821245.015 = 608761846550871.468483

-571270373.546517 >  608762417821245.015: false

-571270373.546517 == 608762417821245.015: false

-571270373.546517 <  608762417821245.015: true

-571270373.546517 >= 608762417821245.015: false

-571270373.546517 <= 608762417821245.015: true
------------------------------------------------

第4组
128261185.021763 - -650.223463 = 128261835.245226
128261185.021763 + -650.223463 = 128260534.798300

128261185.021763 >  -650.223463: true

128261185.021763 == -650.223463: false

128261185.021763 <  -650.223463: false

128261185.021763 >= -650.223463: true

128261185.021763 <= -650.223463: false
------------------------------------------------

第5组
61616.436721 - 33043218771.088144 = -33043157154.651423
61616.436721 + 33043218771.088144 = 33043280387.524865

61616.436721 >  33043218771.088144: false

61616.436721 == 33043218771.088144: false

61616.436721 <  33043218771.088144: true

61616.436721 >= 33043218771.088144: false

61616.436721 <= 33043218771.088144: true
------------------------------------------------

第6组
-870615721.325035 - -185213.632376 = -870430507.692659
-870615721.325035 + -185213.632376 = -870800934.957411

-870615721.325035 >  -185213.632376: false

-870615721.325035 == -185213.632376: false

-870615721.325035 <  -185213.632376: true

-870615721.325035 >= -185213.632376: false

-870615721.325035 <= -185213.632376: true
------------------------------------------------

第7组
1124767517571.72682 - 55438616262.520006 = 1069328901309.206814
1124767517571.72682 + 55438616262.520006 = 1180206133834.246826

1124767517571.72682 >  55438616262.520006: true

1124767517571.72682 == 55438616262.520006: false

1124767517571.72682 <  55438616262.520006: false

1124767517571.72682 >= 55438616262.520006: true

1124767517571.72682 <= 55438616262.520006: false
------------------------------------------------

第8组
323674318651447.714 - -705624841320.74112 = 324379943492768.45512
323674318651447.714 + -705624841320.74112 = 322968693810126.97288

323674318651447.714 >  -705624841320.74112: true

323674318651447.714 == -705624841320.74112: false

323674318651447.714 <  -705624841320.74112: false

323674318651447.714 >= -705624841320.74112: true

323674318651447.714 <= -705624841320.74112: false
------------------------------------------------

第9组
-1144665306707771.6 - 481634332632.706008 = -1145146941040404.306008
-1144665306707771.6 + 481634332632.706008 = -1144183672375138.893992

-1144665306707771.6 >  481634332632.706008: false

-1144665306707771.6 == 481634332632.706008: false

-1144665306707771.6 <  481634332632.706008: true

-1144665306707771.6 >= 481634332632.706008: false

-1144665306707771.6 <= 481634332632.706008: true
------------------------------------------------

第10组
8732.058657 - -782.778583 = 9514.837240
8732.058657 + -782.778583 = 7949.280074

8732.058657 >  -782.778583: true

8732.058657 == -782.778583: false

8732.058657 <  -782.778583: false

8732.058657 >= -782.778583: true

8732.058657 <= -782.778583: false
------------------------------------------------

第11组
25861.444410 - 7026250123802.44388 = -7026250097940.999470
25861.444410 + 7026250123802.44388 = 7026250149663.888290

25861.444410 >  7026250123802.44388: false

25861.444410 == 7026250123802.44388: false

25861.444410 <  7026250123802.44388: true

25861.444410 >= 7026250123802.44388: false

25861.444410 <= 7026250123802.44388: true
------------------------------------------------

第12组
-447.758342 - -22164118630338.377 = 22164118629890.618658
-447.758342 + -22164118630338.377 = -22164118630786.135342

-447.758342 >  -22164118630338.377: true

-447.758342 == -22164118630338.377: false

-447.758342 <  -22164118630338.377: false

-447.758342 >= -22164118630338.377: true

-447.758342 <= -22164118630338.377: false
------------------------------------------------

第13组
8747523615.320310 - 2623811116402745.74 = -2623802368879130.419690
8747523615.320310 + 2623811116402745.74 = 2623819863926361.060310

8747523615.320310 >  2623811116402745.74: false

8747523615.320310 == 2623811116402745.74: false

8747523615.320310 <  2623811116402745.74: true

8747523615.320310 >= 2623811116402745.74: false

8747523615.320310 <= 2623811116402745.74: true
------------------------------------------------

第14组
21.417337 - -841.238130 = 862.655467
21.417337 + -841.238130 = -819.820793

21.417337 >  -841.238130: true

21.417337 == -841.238130: false

21.417337 <  -841.238130: false

21.417337 >= -841.238130: true

21.417337 <= -841.238130: false
------------------------------------------------

第15组
-1540252.622237 - 3301483542760336.28 = -3301483544300588.902237
-1540252.622237 + 3301483542760336.28 = 3301483541220083.657763

-1540252.622237 >  3301483542760336.28: false

-1540252.622237 == 3301483542760336.28: false

-1540252.622237 <  3301483542760336.28: true

-1540252.622237 >= 3301483542760336.28: false

-1540252.622237 <= 3301483542760336.28: true
------------------------------------------------

第16组
804744277.731238 - -57630625470.512714 = 58435369748.243952
804744277.731238 + -57630625470.512714 = -56825881192.781476

804744277.731238 >  -57630625470.512714: true

804744277.731238 == -57630625470.512714: false

804744277.731238 <  -57630625470.512714: false

804744277.731238 >= -57630625470.512714: true

804744277.731238 <= -57630625470.512714: false
------------------------------------------------

第17组
54588025.143467 - 37181153624615.0134 = -37181099036589.869933
54588025.143467 + 37181153624615.0134 = 37181208212640.156867

54588025.143467 >  37181153624615.0134: false

54588025.143467 == 37181153624615.0134: false

54588025.143467 <  37181153624615.0134: true

54588025.143467 >= 37181153624615.0134: false

54588025.143467 <= 37181153624615.0134: true
------------------------------------------------

第18组
-47.444014 - -253.203555 = 205.759541
-47.444014 + -253.203555 = -300.647569

-47.444014 >  -253.203555: true

-47.444014 == -253.203555: false

-47.444014 <  -253.203555: false

-47.444014 >= -253.203555: true

-47.444014 <= -253.203555: false
------------------------------------------------

第19组
6633216310805.67205 - 561852.867423 = 6633215748952.804627
6633216310805.67205 + 561852.867423 = 6633216872658.539473

6633216310805.67205 >  561852.867423: true

6633216310805.67205 == 561852.867423: false

6633216310805.67205 <  561852.867423: false

6633216310805.67205 >= 561852.867423: true

6633216310805.67205 <= 561852.867423: false
------------------------------------------------

第20组
6658841.357124 - -17131451.306243 = 23790292.663367
6658841.357124 + -17131451.306243 = -10472609.949119

6658841.357124 >  -17131451.306243: true

6658841.357124 == -17131451.306243: false

6658841.357124 <  -17131451.306243: false

6658841.357124 >= -17131451.306243: true

6658841.357124 <= -17131451.306243: false
------------------------------------------------

第21组
-200550.220533 - 3284472785364.15405 = -3284472985914.374583
-200550.220533 + 3284472785364.15405 = 3284472584813.933517

-200550.220533 >  3284472785364.15405: false

-200550.220533 == 3284472785364.15405: false

-200550.220533 <  3284472785364.15405: true

-200550.220533 >= 3284472785364.15405: false

-200550.220533 <= 3284472785364.15405: true
------------------------------------------------

第22组
301083560.047325 - -8.655267 = 301083568.702592
301083560.047325 + -8.655267 = 301083551.392058

301083560.047325 >  -8.655267: true

301083560.047325 == -8.655267: false

301083560.047325 <  -8.655267: false

301083560.047325 >= -8.655267: true

301083560.047325 <= -8.655267: false
------------------------------------------------

第23组
148175.157835 - 286266.700022 = -138091.542187
148175.157835 + 286266.700022 = 434441.857857

148175.157835 >  286266.700022: false

148175.157835 == 286266.700022: false

148175.157835 <  286266.700022: true

148175.157835 >= 286266.700022: false

148175.157835 <= 286266.700022: true
------------------------------------------------

第24组
-2621.331256 - -52857260523.474251 = 52857257902.142995
-2621.331256 + -52857260523.474251 = -52857263144.805507

-2621.331256 >  -52857260523.474251: true

-2621.331256 == -52857260523.474251: false

-2621.331256 <  -52857260523.474251: false

-2621.331256 >= -52857260523.474251: true

-2621.331256 <= -52857260523.474251: false
------------------------------------------------

第25组
8773827850628.74812 - 61.476741 = 8773827850567.271379
8773827850628.74812 + 61.476741 = 8773827850690.224861

8773827850628.74812 >  61.476741: true

8773827850628.74812 == 61.476741: false

8773827850628.74812 <  61.476741: false

8773827850628.74812 >= 61.476741: true

8773827850628.74812 <= 61.476741: false
------------------------------------------------

第26组
7351440008672337.43 - -7380726730082.0154 = 7358820735402419.4454
7351440008672337.43 + -7380726730082.0154 = 7344059281942255.4146

7351440008672337.43 >  -7380726730082.0154: true

7351440008672337.43 == -7380726730082.0154: false

7351440008672337.43 <  -7380726730082.0154: false

7351440008672337.43 >= -7380726730082.0154: true

7351440008672337.43 <= -7380726730082.0154: false
------------------------------------------------

第27组
-13383677307.082306 - 3452747742011.25402 = -3466131419318.336326
-13383677307.082306 + 3452747742011.25402 = 3439364064704.171714

-13383677307.082306 >  3452747742011.25402: false

-13383677307.082306 == 3452747742011.25402: false

-13383677307.082306 <  3452747742011.25402: true

-13383677307.082306 >= 3452747742011.25402: false

-13383677307.082306 <= 3452747742011.25402: true
------------------------------------------------

第28组
767613420.170572 - -85462.430530 = 767698882.601102
767613420.170572 + -85462.430530 = 767527957.740042

767613420.170572 >  -85462.430530: true

767613420.170572 == -85462.430530: false

767613420.170572 <  -85462.430530: false

767613420.170572 >= -85462.430530: true

767613420.170572 <= -85462.430530: false
------------------------------------------------

第29组
31813500071.436147 - 6551343.075474 = 31806948728.360673
31813500071.436147 + 6551343.075474 = 31820051414.511621

31813500071.436147 >  6551343.075474: true

31813500071.436147 == 6551343.075474: false

31813500071.436147 <  6551343.075474: false

31813500071.436147 >= 6551343.075474: true

31813500071.436147 <= 6551343.075474: false
------------------------------------------------


E:\Users\admin\Documents\VScode\Code>
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-12-30 15:06:20 | 显示全部楼层
本帖最后由 bin554385863 于 2019-12-30 15:26 编辑

2019年12月30日15:00:34

添加新数据
bool  iszero; 判断一个数字字符串是否为0;

struct attr
    {
        int sign = 1; //符号
        bool iszero = true;//默认为true
        size_t dpsize = 0;     //小数位;
        size_t prec = 0;       //精度
        size_t nsize = 1;      //有效位数
        string str = "0";      //过渡字符串
        vector<int> vec = {0}; //数组;
    };

对应新函数

const bool IsZero(const lnum &l) const;

const bool lnum::IsZero(const lnum &l) const
{
    return !((!num.iszero) || (!l.num.iszero));
}

lnum.h
  1. #ifndef LNUM_H
  2. #define LNUM_H
  3. #include <iostream>
  4. #include <string>
  5. #include <vector>
  6. #include <sstream>
  7. #include <iomanip>
  8. using std::istream;
  9. using std::ostream;
  10. using std::string;
  11. using std::stringstream;
  12. using std::vector;
  13. class lnum
  14. {
  15.     struct attr
  16.     {
  17.         int sign = 1; //符号
  18.         bool iszero = true;
  19.         size_t dpsize = 0;     //小数位;
  20.         size_t prec = 0;       //精度
  21.         size_t nsize = 1;      //有效位数
  22.         string str = "0";      //过渡字符串
  23.         vector<int> vec = {0}; //数组;
  24.     };
  25.     struct align
  26.     {
  27.         vector<int> first;
  28.         vector<int> second;
  29.     };

  30. private:
  31.     //小数精度;
  32.     static size_t precision;
  33.     //数据;
  34.     attr num;
  35.     //str to attr
  36.     const attr StrToAttr(const string &str) const;
  37.     //attr to str
  38.     const string AttrToStr() const;
  39.     //进1
  40.     lnum &Carry();
  41.     //借1
  42.     lnum Borrow();
  43.     //对齐
  44.     const align AlignVec(const vector<int> &m, const vector<int> &n) const;
  45.     //clear zero vec
  46.     lnum &ClearZeroVec();
  47.     //vec to str
  48.     lnum &VecToStr();
  49.     //iszero
  50.     const bool IsZero(const lnum &l) const;

  51. public:
  52.     lnum(const char *cstr = "0") : num(StrToAttr(cstr)) {}
  53.     lnum(const string &str) : num(StrToAttr(str)) {}
  54.     lnum(const lnum &l) : num(l.num) {}
  55.     //------------------------------------------------------------------
  56.     //设置精度
  57.     static void SetPrecision(const size_t i);
  58.     //展示信息
  59.     void Showinfo() const;
  60.     //>
  61.     const bool operator>(const lnum &l) const;
  62.     //<
  63.     const bool operator<(const lnum &l) const;
  64.     //==
  65.     const bool operator==(const lnum &l) const;
  66.     //>=
  67.     const bool operator>=(const lnum &l) const;
  68.     //<=
  69.     const bool operator<=(const lnum &l) const;
  70.     //+
  71.     const lnum operator+(const lnum &l) const;
  72.     //-
  73.     const lnum operator-(const lnum &l) const;
  74.     const lnum operator-() const;
  75.     //+=
  76.     const lnum &operator+=(const lnum &l);
  77.     //++
  78.     const lnum &operator++();
  79.     //-=
  80.     const lnum &operator-=(const lnum &l);
  81.     //--
  82.     const lnum &operator--();
  83.     //odject++
  84.     friend const lnum &operator++(lnum &l, const int i);
  85.     //object--
  86.     friend const lnum &operator--(lnum &l, const int i);
  87.     //>>
  88.     friend istream &operator>>(istream &is, const lnum &l);
  89.     //<<
  90.     friend ostream &operator<<(ostream &os, const lnum &l);
  91. };
  92. size_t lnum::precision = 0;
  93. #endif
复制代码

lnum.cpp
  1. #include "E:\Users\admin\Documents\VScode\Code\My Class\shape.cpp\lnum\lnum.h"
  2. //str to attr
  3. const lnum::attr lnum::StrToAttr(const string &str) const
  4. {
  5.     attr n;
  6.     n.prec = precision;
  7.     n.str = str;
  8.     string &nstr = n.str;
  9.     size_t &ndps = n.dpsize, &npre = n.prec;
  10.     if (nstr[0] == '-')
  11.     {
  12.         nstr.erase(0, 1);
  13.     }
  14.     if (int(nstr.find('.')) != -1)
  15.     {
  16.         nstr.erase(nstr.find('.'), 1);
  17.     }
  18.     if (nstr == string(nstr.size(), '0'))
  19.     {
  20.         nstr.clear();
  21.         nstr.push_back('0');
  22.     }
  23.     else //if (nstr != string(nstr.size(), '0'))
  24.     {
  25.         
  26.         n.iszero = false;//iszero
  27.         size_t s = nstr.size(), i = 0;
  28.         if (str[0] == '-')
  29.         {
  30.             n.sign = -1;
  31.         }
  32.         if (int(str.find('.')) != -1)
  33.         {
  34.             ndps = str.size() - str.find('.') - 1;
  35.             if (nstr[0] == '0')
  36.             {

  37.                 for (; i < s; i++)
  38.                 {
  39.                     if (nstr[i] != '0')
  40.                     {
  41.                         break;
  42.                     }
  43.                 }
  44.                 if (i >= s - ndps)
  45.                 {
  46.                     nstr.erase(0, s - ndps - 1);
  47.                 }
  48.                 else if (i < s - ndps)
  49.                 {
  50.                     nstr.erase(0, i);
  51.                 }
  52.             }
  53.         }
  54.         else
  55.         {
  56.             if (nstr[0] == '0')
  57.             {
  58.                 for (i = 0; i < s; i++)
  59.                 {
  60.                     if (nstr[i] != '0')
  61.                     {
  62.                         break;
  63.                     }
  64.                 }
  65.                 nstr.erase(0, i);
  66.             }
  67.         }
  68.         if (npre > ndps)
  69.         {
  70.             nstr.insert(nstr.end(), npre - ndps, '0');
  71.         }
  72.         else if (npre < ndps)
  73.         {
  74.             nstr.erase(nstr.size() - (ndps - npre));
  75.             ndps = npre;
  76.         }
  77.         n.vec.clear();
  78.         for (char c : nstr)
  79.         {
  80.             n.vec.push_back(c - 48);
  81.         }
  82.         n.nsize = nstr.size();
  83.     }
  84.     return n;
  85. }
  86. //attr to str
  87. const string lnum::AttrToStr() const
  88. {
  89.     string t = num.str, &str = t;
  90.     const size_t &prec = num.prec, &dpsize = num.dpsize;
  91.     if (prec != 0 && str.size() != 1)
  92.     {
  93.         if (dpsize == prec)
  94.         {
  95.             str.insert(str.size() - prec, 1, '.');
  96.         }
  97.         else if (dpsize < prec && dpsize != 0)
  98.         {
  99.             str.erase(str.size() - (prec - dpsize));
  100.             str.insert(str.size() - dpsize, 1, '.');
  101.         }
  102.         else if (dpsize == 0)
  103.         {
  104.             str.erase(str.size() - prec);
  105.         }
  106.     }
  107.     if (num.sign == -1)
  108.     {
  109.         str.insert(0, 1, '-');
  110.     }
  111.     return str;
  112. }
  113. //进1
  114. lnum &lnum::Carry()
  115. {
  116.     vector<int> &v = num.vec;
  117.     v.insert(v.begin(), 1, 0);
  118.     size_t s = v.size();
  119.     for (size_t i = s - 1; i > 0; i--)
  120.     {
  121.         int t = v[i];
  122.         v[i] = t % 10;
  123.         v[i - 1] += t / 10;
  124.     }
  125.     return *this;
  126. }
  127. //借1
  128. lnum lnum::Borrow()
  129. {
  130.     vector<int> &v = num.vec;
  131.     size_t s = v.size();
  132.     for (size_t i = 1; i < s; i++)
  133.     {
  134.         v[i - 1] -= 1;
  135.         v[i] += 10;
  136.     }
  137.     return *this;
  138. }
  139. //对齐
  140. const lnum::align lnum::AlignVec(const vector<int> &m, const vector<int> &n) const
  141. {
  142.     align agn;
  143.     vector<int> &fst = agn.first, &sec = agn.second;
  144.     fst = m, sec = n;
  145.     size_t fsize = fst.size(), ssize = sec.size();
  146.     if (fsize < ssize)
  147.     {
  148.         fst.insert(fst.begin(), ssize - fsize, 0);
  149.     }
  150.     else if (fsize > ssize)
  151.     {
  152.         sec.insert(sec.begin(), fsize - ssize, 0);
  153.     }
  154.     return agn;
  155. }
  156. //clear zero vec
  157. lnum &lnum::ClearZeroVec()
  158. {
  159.     const size_t &prec = num.prec;
  160.     vector<int> &v = num.vec;
  161.    
  162.     if (num.iszero)//v == vector<int>(v.size(), 0)
  163.     {
  164.         v.clear();
  165.         v.push_back(0);
  166.     }
  167.     else if (v[0] == 0)
  168.     {
  169.         size_t s = v.size(), i = 0;
  170.         if (prec != 0)
  171.         {

  172.             for (; i < s; i++)
  173.             {
  174.                 if (v[i] != 0)
  175.                 {
  176.                     break;
  177.                 }
  178.             }
  179.             if (i >= s - prec)
  180.             {
  181.                 v.erase(v.begin(), v.begin() + (s - prec - 1));
  182.             }
  183.             else if (i < s - prec)
  184.             {
  185.                 v.erase(v.begin(), v.begin() + i);
  186.             }
  187.         }
  188.         else
  189.         {
  190.             for (i = 0; i < s; i++)
  191.             {
  192.                 if (v[i] != 0)
  193.                 {
  194.                     break;
  195.                 }
  196.             }
  197.             v.erase(v.begin(), v.begin() + i);
  198.         }
  199.     }
  200.     return *this;
  201. }
  202. //vec to str
  203. lnum &lnum::VecToStr()
  204. {
  205.     num.str.clear();
  206.     for (int i : num.vec)
  207.     {
  208.         num.str.push_back(i + 48);
  209.     }
  210.     return *this;
  211. }
  212. //iszero
  213. const bool lnum::IsZero(const lnum &l) const
  214. {
  215.     return !((!num.iszero) || (!l.num.iszero));
  216. }
  217. //------------------------------------------------------------------------
  218. //设置精度
  219. void lnum::SetPrecision(const size_t i)
  220. {
  221.     lnum::precision = i;
  222. }
  223. //展示信息
  224. void lnum::Showinfo() const
  225. {
  226.     std::cout << "有效数位: ";
  227.     for (int i : num.vec)
  228.     {
  229.         std::cout << i << " ";
  230.     }
  231.     std::cout << std::endl;
  232.     std::cout << "正负符号: " << num.sign << "\n"
  233.               << std::boolalpha << "是否为零: " << num.iszero << "\n"
  234.               << "小数位数: " << num.dpsize << "\n"
  235.               << "小数精度: " << num.prec << "\n"
  236.               << "有效位数: " << num.nsize << std::endl;
  237. }
  238. //>
  239. const bool lnum::operator>(const lnum &l) const
  240. {
  241.     bool f = true;
  242.     align agn = AlignVec(num.vec, l.num.vec);
  243.     const vector<int> &fst = agn.first, &sec = agn.second;
  244.     if (num.sign < l.num.sign)
  245.     {
  246.         f = false;
  247.     }
  248.     if (num.sign == l.num.sign)
  249.     {
  250.         f = fst > sec;
  251.         if (num.sign == -1)
  252.         {
  253.             f = !f;
  254.         }
  255.     }
  256.     return f;
  257. }
  258. //<
  259. const bool lnum::operator<(const lnum &l) const
  260. {
  261.     bool f = true;
  262.     align agn = AlignVec(num.vec, l.num.vec);
  263.     const vector<int> &fst = agn.first, &sec = agn.second;
  264.     if (num.sign > l.num.sign)
  265.     {
  266.         f = false;
  267.     }
  268.     if (num.sign == l.num.sign)
  269.     {
  270.         f = fst < sec;
  271.         if (num.sign == -1)
  272.         {
  273.             f = !f;
  274.         }
  275.     }
  276.     return f;
  277. }
  278. //==
  279. const bool lnum::operator==(const lnum &l) const
  280. {
  281.     align agn = AlignVec(num.vec, l.num.vec);
  282.     const vector<int> &fst = agn.first, &sec = agn.second;
  283.     return fst == sec && num.sign == l.num.sign;
  284. }
  285. //>=
  286. const bool lnum::operator>=(const lnum &l) const
  287. {
  288.     return !(*this < l);
  289. }
  290. //<=
  291. const bool lnum::operator<=(const lnum &l) const
  292. {
  293.     return !(*this > l);
  294. }
  295. //+
  296. const lnum lnum::operator+(const lnum &l) const
  297. {

  298.     lnum r;
  299.     attr &lr = r.num;
  300.     lr.iszero = this->IsZero(l);
  301.     const align &agn = AlignVec(num.vec, l.num.vec);
  302.     const int &tsgn = num.sign, &lsgn = l.num.sign;
  303.     const vector<int> &fst = agn.first, &sec = agn.second, &tvec = num.vec, &lvec = l.num.vec;
  304.     lr.prec = num.prec;
  305.     lr.dpsize = (num.dpsize >= l.num.dpsize ? num.dpsize : l.num.dpsize);
  306.     size_t s = (fst.size() <= sec.size() ? fst.size() : sec.size());
  307.     lr.vec = (fst >= sec ? fst : sec);
  308.     for (size_t i = 0; i < s; i++)
  309.     {
  310.         lr.vec[i] += (tsgn * lsgn) * ((sec <= fst ? sec : fst)[i]);
  311.     }
  312.     if ((fst > sec && tsgn < lsgn) || (fst < sec && tsgn > lsgn) || (tsgn == -1 && lsgn == -1))
  313.     {
  314.         lr.sign = -1;
  315.     }
  316.     if (tsgn * lsgn == -1)
  317.     {
  318.         r.Borrow();
  319.     }
  320.     r.Carry().ClearZeroVec().VecToStr();
  321.     lr.nsize = lr.vec.size();
  322.     return r;
  323. }
  324. //符号取反
  325. const lnum lnum::operator-() const
  326. {
  327.     const vector<int> &tvec = num.vec;
  328.     lnum r = *this;
  329.     if (num.iszero == false)//(tvec != vector<int>(tvec.size(), 0))
  330.     {
  331.         r.num.sign = -num.sign;
  332.     }
  333.     return r;
  334. }
  335. //-
  336. const lnum lnum::operator-(const lnum &l) const
  337. {
  338.     lnum r;
  339.     r.num.iszero = this->IsZero(l);
  340.     if (l.num.iszero == false)//(l.num.vec != vector<int>(1, 0))
  341.     {
  342.         r = *this + (-l);
  343.     }
  344.     else
  345.     {
  346.         r = *this;
  347.     }
  348.     return r;
  349. }
  350. //+=
  351. const lnum &lnum::operator+=(const lnum &l)
  352. {
  353.     *this = *this + l;
  354.     return *this;
  355. }
  356. //前置++
  357. const lnum &lnum::operator++()
  358. {
  359.     return *this += "1";
  360. }
  361. //-=
  362. const lnum &lnum::operator-=(const lnum &l)
  363. {
  364.     *this = *this - l;
  365.     return *this;
  366. }
  367. //前置--
  368. const lnum &lnum::operator--()
  369. {
  370.     return *this -= "1";
  371. }
  372. //后置++
  373. const lnum &operator++(lnum &l, const int i)
  374. {
  375.     return ++l;
  376. }
  377. //后置--
  378. const lnum &operator--(lnum &l, const int i)
  379. {
  380.     return --l;
  381. }
  382. //>>
  383. istream &operator>>(istream &is, lnum &l)
  384. {
  385.     string str;
  386.     (is >> str).get();
  387.     l = str;
  388.     return is;
  389. }
  390. //<<
  391. ostream &operator<<(ostream &os, const lnum &l)
  392. {
  393.     os << l.AttrToStr();
  394.     return os;
  395. }
复制代码

test.cpp
  1. #include "E:\Users\admin\Documents\VScode\Code\My Class\shape.cpp\lnum\lnum.cpp"
  2. #include <ctime>
  3. #include <cmath>
  4. int main(int argc, char const *argv[])
  5. {
  6.     int s = 0;
  7.     lnum::SetPrecision(6);
  8.     lnum a, b;
  9.     char n[9], m[9];
  10.     n[8] = m[8] = '\0';
  11.     srand(time(NULL));
  12.     while (s != 12)
  13.     {
  14.         for (size_t i = 0; i < 8; i++)
  15.         {
  16.             n[i] = rand() % 9 + 48;

  17.             m[i] = rand() % 9 + 48;
  18.         }
  19.         n[rand() % 6 + 1] = '.';
  20.         m[rand() % 6 + 1] = '.';
  21.         if (s % 2 == 0)
  22.         {
  23.             n[0] = '-';
  24.         }
  25.         if (s % 3 == 0)
  26.         {
  27.             m[0] = '-';
  28.         }
  29.         a = m;
  30.         b = n;
  31.         std::cout << "第" << s << "组" << std::endl;
  32.         std::cout << a << " - " << b << " = " << (a - b) << "\n"
  33.                   << a << " + " << b << " = " << (a + b) << "\n\n"
  34.                   << std::boolalpha
  35.                   << a << " >  " << b << ": " << (a > b) << "\n\n"
  36.                   << a << " == " << b << ": " << (a == b) << "\n\n"
  37.                   << a << " <  " << b << ": " << (a < b) << "\n\n"
  38.                   << a << " >= " << b << ": " << (a >= b) << "\n\n"
  39.                   << a << " <= " << b << ": " << (a <= b) << "\n"
  40.                   << "------------------------------------------------"
  41.                   << "\n\n";
  42.         s++;
  43.     }
  44.     return 0;
  45. }
复制代码

---------------------------------------------------------------------------------------------
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-r4eqqtl4.g4x --stdout=Microsoft-MIEngine-Out-tdxveute.slr --stderr=Microsoft-MIEngine-Error-mmf3t4g3.0vo --pid=Microsoft-MIEngine-Pid-ube4pyyu.txb --dbgExe=D:\MinGW\bin\gdb.exe --interpreter=mi
第0组
-65066.5 - -28541.3 = -36525.2
-65066.5 + -28541.3 = -93607.8

-65066.5 >  -28541.3: false   

-65066.5 == -28541.3: false   

-65066.5 <  -28541.3: true   

-65066.5 >= -28541.3: false

-65066.5 <= -28541.3: true
------------------------------------------------

第1组
45.31752 - 86.42017 = -41.10265
45.31752 + 86.42017 = 131.73769

45.31752 >  86.42017: false

45.31752 == 86.42017: false

45.31752 <  86.42017: true

45.31752 >= 86.42017: false

45.31752 <= 86.42017: true
------------------------------------------------

第2组
5.601777 - -65.7413 = 71.343077
5.601777 + -65.7413 = -60.139523

5.601777 >  -65.7413: true

5.601777 == -65.7413: false

5.601777 <  -65.7413: false

5.601777 >= -65.7413: true

5.601777 <= -65.7413: false
------------------------------------------------

第3组
-6618.72 - 581607.6 = -588226.32
-6618.72 + 581607.6 = 574988.88

-6618.72 >  581607.6: false

-6618.72 == 581607.6: false

-6618.72 <  581607.6: true

-6618.72 >= 581607.6: false

-6618.72 <= 581607.6: true
------------------------------------------------

第4组
36812.51 - -27147.1 = 63959.61
36812.51 + -27147.1 = 9665.41

36812.51 >  -27147.1: true

36812.51 == -27147.1: false

36812.51 <  -27147.1: false

36812.51 >= -27147.1: true

36812.51 <= -27147.1: false
------------------------------------------------

第5组
445684.7 - 4821.640 = 440863.060
445684.7 + 4821.640 = 450506.340

445684.7 >  4821.640: true

445684.7 == 4821.640: false

445684.7 <  4821.640: false

445684.7 >= 4821.640: true

445684.7 <= 4821.640: false
------------------------------------------------

第6组
-.650710 - -4.45786 = 3.807150
-.650710 + -4.45786 = -5.108570

-.650710 >  -4.45786: true

-.650710 == -4.45786: false

-.650710 <  -4.45786: false

-.650710 >= -4.45786: true

-.650710 <= -4.45786: false
------------------------------------------------

第7组
154.2605 - 350.4061 = -196.1456
154.2605 + 350.4061 = 504.6666

154.2605 >  350.4061: false

154.2605 == 350.4061: false

154.2605 <  350.4061: true

154.2605 >= 350.4061: false

154.2605 <= 350.4061: true
------------------------------------------------

第8组
47.87481 - -5507.32 = 5555.19481
47.87481 + -5507.32 = -5459.44519

47.87481 >  -5507.32: true

47.87481 == -5507.32: false

47.87481 <  -5507.32: false

47.87481 >= -5507.32: true

47.87481 <= -5507.32: false
------------------------------------------------

第9组
-653.76 - 680005.7 = -680659.46
-653.76 + 680005.7 = 679351.94

-653.76 >  680005.7: false

-653.76 == 680005.7: false

-653.76 <  680005.7: true

-653.76 >= 680005.7: false

-653.76 <= 680005.7: true
------------------------------------------------

第10组
462520.0 - -28804.2 = 491324.2
462520.0 + -28804.2 = 433715.8

462520.0 >  -28804.2: true

462520.0 == -28804.2: false

462520.0 <  -28804.2: false

462520.0 >= -28804.2: true

462520.0 <= -28804.2: false
------------------------------------------------

第11组
746407.4 - 150352.6 = 596054.8
746407.4 + 150352.6 = 896760.0

746407.4 >  150352.6: true

746407.4 == 150352.6: false

746407.4 <  150352.6: false

746407.4 >= 150352.6: true

746407.4 <= 150352.6: false
------------------------------------------------


E:\Users\admin\Documents\VScode\Code>
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-7-5 04:08

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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