|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 bin554385863 于 2019-12-28 20:30 编辑
lnum.h
目前只支持同号加法
- #ifndef LNUM_H
- #define LNUM_H
- #include <iostream>
- #include <string>
- #include <vector>
- using std::istream;
- using std::ostream;
- using std::string;
- using std::vector;
- class lnum
- {
- struct attr
- {
- int sign = 1; //符号;
- size_t dpsize = 0; //小数位;
- size_t prec = 0; //精度
- size_t nsize = 1; //有效位数
- string str = "0"; //过渡字符串
- vector<int> vec = {0}; //数组;
- };
- struct align
- {
- vector<int> first;
- vector<int> second;
- };
- private:
- //小数精度;
- static size_t precision;
- //数据;
- attr num;
- //str to attr
- const attr StrToAttr(const string &str) const;
- //attr to str
- const string AttrToStr() const;
- //进1
- lnum &Carry();
- //借1
- vector<int> Borrow() const;
- //对齐
- const align AlignVec(const vector<int> &m, const vector<int> &n) const;
- //反转正负
- vector<int> Negative() const;
- //clear zero vec
- lnum &ClearZeroVec();
- //vec to str
- lnum &VecToStr();
- public:
- lnum(const char *cstr = "0") : num(StrToAttr(cstr))
- {
- }
- lnum(const string &str) : num(StrToAttr(str)) {}
- lnum(const lnum &l) : num(l.num) {}
- //------------------------------------------------------------------
- //设置精度
- static void SetPrecision(const size_t i);
- //展示信息
- void Showinfo() const;
- //>
- const bool operator>(const lnum &l) const;
- //<
- const bool operator<(const lnum &l) const;
- //==
- const bool operator==(const lnum &l) const;
- //>=
- const bool operator>=(const lnum &l) const;
- //<=
- const bool operator<=(const lnum &l) const;
- //+
- const lnum operator+(const lnum &l) const;
- //-
- const lnum operator-(const lnum &l) const;
- //>>
- friend istream &operator>>(istream &is, const lnum &l);
- //<<
- friend ostream &operator<<(ostream &os, const lnum &l);
- };
- size_t lnum::precision = 0;
- #endif
复制代码
lnum.cpp
- #include "E:\Users\admin\Documents\VScode\Code\My Class\shape.cpp\lnum\lnum.h"
- //str to attr
- const lnum::attr lnum::StrToAttr(const string &str) const
- {
- attr n;
- n.prec = precision;
- n.str = str;
- string &nstr = n.str;
- if (nstr[0] == '-')
- {
- nstr.erase(0, 1);
- }
- if (int(nstr.find('.')) != -1)
- {
- nstr.erase(nstr.find('.'), 1);
- }
- if (nstr == string(nstr.size(), '0'))
- {
- nstr.clear();
- nstr.push_back('0');
- }
- else if (nstr != string(nstr.size(), '0'))
- {
- size_t s = nstr.size(), i = 0;
- if (str[0] == '-')
- {
- n.sign = -1;
- }
- if (int(str.find('.')) != -1)
- {
- n.dpsize = str.size() - str.find('.') - 1;
- if (nstr[0] == '0')
- {
- for (; i < s; i++)
- {
- if (nstr[i] != '0')
- {
- break;
- }
- }
- if (i >= s - n.dpsize)
- {
- nstr.erase(0, s - n.dpsize - 1);
- }
- else if (i < s - n.dpsize)
- {
- nstr.erase(0, i);
- }
- }
- }
- else
- {
- if (nstr[0] == '0')
- {
- for (i = 0; i < s; i++)
- {
- if (nstr[i] != '0')
- {
- break;
- }
- }
- nstr.erase(0, i);
- }
- }
- if (n.prec > n.dpsize)
- {
- nstr.insert(nstr.end(), n.prec - n.dpsize, '0');
- }
- else if (n.prec < n.dpsize)
- {
- nstr.erase(nstr.size() - (n.dpsize - n.prec));
- n.dpsize = n.prec;
- }
- n.vec.clear();
- for (char c : nstr)
- {
- n.vec.push_back(c - 48);
- }
- n.nsize = nstr.size();
- }
- return n;
- }
- //attr to str
- const string lnum::AttrToStr() const
- {
- string str = num.str;
- const size_t &prec = num.prec, &dpsize = num.dpsize;
- if (str.size() != 1 && prec != 0)
- {
- if (dpsize == prec)
- {
- str.insert(str.size() - prec, 1, '.');
- }
- else if (dpsize < prec && dpsize != 0)
- {
- str.erase(str.size() - (prec - dpsize));
- str.insert(str.size() - dpsize, 1, '.');
- }
- else if (dpsize == 0)
- {
- str.erase(str.size() - prec);
- }
- }
- if (num.sign == -1)
- {
- str.insert(0, 1, '-');
- }
- return str;
- }
- //进1
- lnum &lnum::Carry()
- {
- vector<int> &v = num.vec;
- v.insert(v.begin(), 1, 0);
- size_t s = v.size();
- for (size_t i = s - 1; i > 0; i--)
- {
- int t = v[i];
- v[i] = t % 10;
- v[i - 1] += t / 10;
- }
- return *this;
- }
- //借1
- vector<int> lnum::Borrow() const
- {
- vector<int> t = num.vec;
- size_t s = t.size();
- for (size_t i = 1; i < s; i++)
- {
- t[i - 1] -= 1;
- t[i] += 10;
- }
- return t;
- }
- //对齐
- const lnum::align lnum::AlignVec(const vector<int> &m, const vector<int> &n) const
- {
- align agn;
- vector<int> &fst = agn.first, &sec = agn.second;
- fst = m, sec = n;
- size_t fsize = fst.size(), ssize = sec.size();
- if (fsize < ssize)
- {
- fst.insert(fst.begin(), ssize - fsize, 0);
- }
- else if (fsize > ssize)
- {
- sec.insert(sec.begin(), fsize - ssize, 0);
- }
- return agn;
- }
- //反转正负
- vector<int> lnum::Negative() const
- {
- auto r = num.vec;
- for (int &i : r)
- {
- i = -1;
- }
- return r;
- }
- //clear zero vec
- lnum &lnum::ClearZeroVec()
- {
- const size_t &prec = num.prec;
- vector<int> &v = num.vec;
- if (v == vector<int>(v.size(), 0))
- {
- v.clear();
- v.push_back(0);
- }
- else if (v[0] == 0)
- {
- size_t s = v.size(), i = 0;
- if (prec != 0)
- {
-
- for (; i < s; i++)
- {
- if (v[i] != 0)
- {
- break;
- }
- }
- if (i >= s - prec)
- {
- v.erase(v.begin(), v.begin() + (s - prec - 1));
- }
- else if (i < s - prec)
- {
- v.erase(v.begin(), v.begin() + i);
- }
- }
- else
- {
- for ( i = 0; i < s; i++)
- {
- if (v[i] != 0)
- {
- break;
- }
- }
- v.erase(v.begin(), v.begin() + i);
- }
-
- }
- return *this;
- }
- //vec to str
- lnum &lnum::VecToStr()
- {
- num.str.clear();
- for (int i : num.vec)
- {
- num.str.push_back(i + 48);
- }
- return *this;
- }
- //------------------------------------------------------------------------
- //设置精度
- void lnum::SetPrecision(const size_t i)
- {
- lnum::precision = i;
- }
- //展示信息
- void lnum::Showinfo() const
- {
- std::cout << "有效数位: ";
- for (int i : num.vec)
- {
- std::cout << i << " ";
- }
- std::cout << std::endl;
- std::cout << "正负符号: " << num.sign << "\n"
- << "小数位数: " << num.dpsize << "\n"
- << "小数精度: " << num.prec << "\n"
- << "有效位数: " << num.nsize << std::endl;
- }
- //>
- const bool lnum::operator>(const lnum &l) const
- {
- bool f = true;
- align agn = AlignVec(num.vec, l.num.vec);
- const vector<int> &fst = agn.first, &sec = agn.second;
- if (num.sign < l.num.sign)
- {
- f = false;
- }
- if (num.sign == l.num.sign)
- {
- f = fst > sec;
- if (num.sign == -1)
- {
- f = !f;
- }
- }
- return f;
- }
- //<
- const bool lnum::operator<(const lnum &l) const
- {
- bool f = true;
- align agn = AlignVec(num.vec, l.num.vec);
- const vector<int> &fst = agn.first, &sec = agn.second;
- if (num.sign > l.num.sign)
- {
- f = false;
- }
- if (num.sign == l.num.sign)
- {
- f = fst < sec;
- if (num.sign == -1)
- {
- f = !f;
- }
- }
- return f;
- }
- //==
- const bool lnum::operator==(const lnum &l) const
- {
- align agn = AlignVec(num.vec, l.num.vec);
- const vector<int> &fst = agn.first, &sec = agn.second;
- return fst == sec && num.sign == l.num.sign;
- }
- //>=
- const bool lnum::operator>=(const lnum &l) const
- {
- return !(*this < l);
- }
- //<=
- const bool lnum::operator<=(const lnum &l) const
- {
- return !(*this > l);
- }
- //+
- const lnum lnum::operator+(const lnum &l) const
- {
- lnum r;
- attr &lr = r.num;
- const size_t &prec = num.prec, &dpsize = num.dpsize, &ldps = l.num.dpsize;
- if ((num.vec == vector<int>(1, 0)) && (l.num.vec == vector<int>(1, 0)))
- {
- lr.prec = num.prec;
- }
- else if ((num.vec != vector<int>(1, 0)) || (l.num.vec != vector<int>(1, 0)))
- {
- const align &agn = AlignVec(num.vec, l.num.vec);
- const vector<int> &fst = agn.first,
- &sec = agn.second,
- &tvec = this->num.vec,
- &lvec = l.num.vec;
- lr.prec = prec;
- lr.dpsize = dpsize >= ldps ? dpsize : ldps;
- if (num.sign == l.num.sign)
- {
- lr.sign = num.sign;
- if (((tvec == vector<int>(1, 0)) && (lvec != vector<int>(1, 0))) ||((tvec != vector<int>(1, 0)) && (lvec == vector<int>(1, 0))))
- {
- lr.vec = num.nsize > l.num.nsize ? tvec : lvec;
- }
- else if ((tvec != vector<int>(1, 0)) && (lvec != vector<int>(1, 0)))
- {
- size_t s = fst.size();
- lr.vec = fst;
- for (size_t i = 0; i < s; i++)
- {
- lr.vec[i] += sec[i];
- }
- }
- r.Carry().ClearZeroVec().VecToStr();
- lr.nsize = lr.vec.size();
- }
- else
- {
- r = *this - l;
- }
- }
- return r;
- }
- //-
- const lnum lnum::operator-(const lnum &l) const
- {
- }
- //>>
- istream &operator>>(istream &is, lnum &l)
- {
- string str;
- (is >> str).get();
- l = str;
- return is;
- }
- //<<
- ostream &operator<<(ostream &os, const lnum &l)
- {
- os << l.AttrToStr();
- return os;
- }
复制代码
lnum_test.cpp
- #include "E:\Users\admin\Documents\VScode\Code\My Class\shape.cpp\lnum\lnum.cpp"
- int main(int argc, char const *argv[])
- {
- lnum::SetPrecision(3);
- lnum a, b, c;
- int i = 0;
- while (i != 5)
- {
- std::cout << "input data\n";
- std::cin >> a >> b;
- std::cout << "a = " << a << " "
- << "b = " << b << "\n"
- << "a + b = " << (a + b) << std::endl;
- std::cout << std::endl;
- i++;
- }
-
- return 0;
- }
复制代码
======================================================
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
- #include "E:\Users\admin\Documents\VScode\Code\My Class\shape.cpp\lnum\lnum.cpp"
- int main(int argc, char const *argv[])
- {
- lnum::SetPrecision(3);
- lnum a, b, c;
- int i = 0;
- while (i != 5)
- {
- std::cout << "input data\n";
- std::cin >> a >> b;
- std::cout << std::boolalpha << "a = " << a << " "
- << "b = " << b << "\n"
- << "a >= b: " << (a >= b) << "\n"
- << "a > b: " << (a > b) << "\n"
- << "a <= b: " << (a <= b) << "\n"
- << "a < b: " << (a < b) << "\n"
- << "a == b: " << (a == b);
- std::cout << std::endl;
- i++;
- }
-
- return 0;
- }
复制代码
================================================
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> |
|