|
楼主 |
发表于 2020-1-3 18:08:54
|
显示全部楼层
__优化代码
__添加算法
__实现精度输出
lnum.cpp
- #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
- {
- typedef vector<int> vecint;
- struct attr
- {
- string str = "0";
- int sign = 0;
- vecint vec = {0};
- size_t nsize = 1, dsize = 0;
- };
- struct align
- {
- vecint first, second;
- };
-
- private:
- attr num;
- static size_t precision;
- //初始化构造函数的数据
- const attr InitData(const string &s);
- //判断是否有效的数字字符串
- const bool IsNumStr(const string &s) const;
- //判断字符串元素是否全为'0'
- const bool IsStrElemZero(const string &s) const;
- //清除无效的0
- const string ClearStrZero(const string &s) const;
- //获取正负符号
- const int getSign(const string &s) const;
- //获取数组
- const vecint Str2Vec(const string &s) const;
- //获取数字字符串
- const string Vec2Str(const vecint &v, int sgn, size_t dps) const;
- //获取小数位数
- const size_t getDsize(const string &s) const;
- //整体对齐
- const align nAlign(const lnum &l) const;
- //小数位对齐
- const align dAlign(const lnum &l) const;
- //满十进一
- void Carry(vecint &v) const;
- //借一
- void Borrow(vecint &v) const;
- //数组乘整数
- lnum operator*(const int i) const;
- //输出字符串
- const string outPutStr() const;
- public:
- lnum(const char *cstr = "0") : num(InitData(cstr)) {}
- lnum(const string &s) : num(InitData(s)) {}
- lnum(const lnum &l) : num(l.num) {}
- void showinfo() const;
- //(1)重载>
- const bool operator>(const lnum &l) const;
- //(2)重载==
- const bool operator==(const lnum &l) const;
- //(2.5)重载!=
- const bool operator!=(const lnum &l) const;
- //(3)重载>=
- const bool operator>=(const lnum &l) const;
- //(4)重载<
- const bool operator<(const lnum &l) const;
- //(5)重载<=
- const bool operator<=(const lnum &l) const;
- //(6)重载+
- const lnum operator+(const lnum &l) const;
- //(7)重载-,反转正负
- const lnum operator-() const;
- //(8)重载-
- const lnum operator-(const lnum &l) const;
- //(9)重载+=
- const lnum &operator+=(const lnum &l);
- //(10)重载++
- const lnum &operator++();
- //(11)重载-=
- const lnum &operator-=(const lnum &l);
- //(12)重载--
- const lnum &operator--();
- //(13)前置++
- friend const lnum &operator++(lnum &l, const int i);
- //(14)前置--
- friend const lnum &operator--(lnum &l, const int i);
- void static setprecision(const unsigned i);
- friend ostream &operator<<(ostream &os, const lnum &l);
- friend istream &operator>>(istream &is, lnum &l);
- virtual ~lnum() {}
- };
- size_t lnum::precision = 0;
- #endif
复制代码
lnum.cpp
- #include "E:\Users\admin\Documents\VScode\Code\My Class\largenum\lnum.h"
- //(1)初始化构造函数的数据
- const lnum::attr lnum::InitData(const string &s)
- {
- attr n = {ClearStrZero(s),
- getSign(n.str),
- Str2Vec(n.str),
- n.vec.size(),
- getDsize(n.str)};
- return n;
- }
- //(2)判断是否有效的数字字符串
- const bool lnum::IsNumStr(const string &s) const
- {
- bool f = true;
- string str = s;
- if (str[0] == '-')
- {
- str.erase(0, 1);
- }
- if (int(str.find('.')) == -1)
- {
- for (char &c : str)
- {
- if (!isdigit(c))
- {
- f = false;
- break;
- }
- }
- }
- else
- {
- if ((str.find('.') == 0) || (str.find('.')) == (str.size() - 1) || (s.find('.') != s.rfind('.')))
- {
- f = false;
- }
- else
- {
- str.erase(str.find('.'), 1);
- for (char &c : str)
- {
- if (!isdigit(c))
- {
- f = false;
- break;
- }
- }
- }
- }
- return f;
- }
- //(3)判断字符串元素是否全为'0'
- const bool lnum::IsStrElemZero(const string &s) const
- {
- bool f = false;
- string str = s;
- if (str[0] == '-')
- {
- str.erase(0, 1);
- }
- if (int(s.find('.')) != -1)
- {
- str.erase(str.find('.'), 1);
- }
- if (str == string(str.size(), '0'))
- {
- f = true;
- }
- return f;
- }
- //(4)清除无效的0
- const string lnum::ClearStrZero(const string &s) const
- {
- string str = "0";
- if (IsNumStr(s) && (!IsStrElemZero(s)))
- {
- str = s;
- if (str[0] == '-')
- {
- str.erase(0, 1);
- }
- size_t i = 0;
- if (int(s.find('.')) == -1)
- {
- size_t sz = str.size();
- while (i != sz)
- {
- if (str[i] != '0')
- {
- break;
- }
- i++;
- }
- if (i == sz)
- {
- str.erase(0, i - 1);
- }
- else
- {
- str.erase(0, i);
- }
- }
- else
- {
- i = 0;
- while (str[i] != '.')
- {
- if (str[i] != '0')
- {
- break;
- }
- i++;
- }
- if (i == str.find('.'))
- {
- str.erase(0, i - 1);
- }
- else
- {
- str.erase(0, i);
- }
- i = str.size() - 1;
- while (str[i] != '.')
- {
- if (str[i] != '0')
- {
- break;
- }
- i--;
- }
- if (i == str.find('.'))
- {
- str.erase(i);
- }
- else if (i < str.size() - 1)
- {
- str.erase(i + 1);
- }
- }
- if (s[0] == '-')
- {
- str.insert(0, 1, '-');
- }
- }
- return str;
- }
- //(5)获取正负符号
- const int lnum::getSign(const string &s) const
- {
- int sgn = 0;
- if (s != "0")
- {
- sgn = s[0] == '-' ? -1 : 1;
- }
- return sgn;
- }
- //(6)获取数组
- const lnum::vecint lnum::Str2Vec(const string &s) const
- {
- vecint v = {0};
- if (IsNumStr(s))
- {
- string str = s;
- if (str[0] == '-')
- {
- str.erase(0, 1);
- }
- if (int(s.find('.')) != -1)
- {
- str.erase(str.find('.'), 1);
- }
- v.clear();
- for (char &c : str)
- {
- v.push_back(c - 48);
- }
- }
- return v;
- }
- //(7)获取数字字符串
- const string lnum::Vec2Str(const vecint &v, int sgn, size_t dps) const
- {
- string str = "0";
- if (sgn != 0)
- {
- str.clear();
- for (const int &i : v)
- {
- str.push_back(i + 48);
- }
- if (dps != 0)
- {
- str.insert(str.size() - dps, 1, '.');
- }
- if (sgn == -1)
- {
- str.insert(0, 1, '-');
- }
- }
- return str;
- }
- //(8)获取小数位数
- const size_t lnum::getDsize(const string &s) const
- {
- size_t dps = 0;
- if (s.find('.') != -1)
- {
- dps = s.size() - s.find('.') - 1;
- }
- return dps;
- }
- //(9)整体对齐
- const lnum::align lnum::nAlign(const lnum &l) const
- {
- align agn;
- const vecint &tvec = num.vec, &lvec = l.num.vec;
- vecint &fst = agn.first, &sec = agn.second;
- const size_t &tdps = num.dsize, &ldps = l.num.dsize;
- fst = tvec;
- sec = lvec;
- tdps > ldps ? sec.insert(sec.end(), tdps - ldps, 0) : fst.insert(fst.end(), ldps - tdps, 0);
- const size_t &fsz = fst.size(), &ssz = sec.size();
- fsz > ssz ? sec.insert(sec.begin(), fsz - ssz, 0) : fst.insert(fst.begin(), ssz - fsz, 0);
- return agn;
- }
- //(10)小数位对齐
- const lnum::align lnum::dAlign(const lnum &l) const
- {
- align agn;
- vecint &fst = agn.first, &sec = agn.second;
- const size_t &tdps = num.dsize, &ldps = l.num.dsize;
- fst = num.vec;
- sec = l.num.vec;
- tdps > ldps ? sec.insert(sec.end(), tdps - ldps, 0) : fst.insert(fst.end(), ldps - tdps, 0);
- return agn;
- }
- //满十进一
- void lnum::Carry(vecint &v) const
- {
- v.insert(v.begin(), 1, 0);
- size_t sz = v.size();
- for (size_t i = sz - 1; i > 0; i--)
- {
- int t = v[i];
- v[i] = t % 10;
- v[i - 1] += t / 10;
- }
- }
- //借一
- void lnum::Borrow(vecint &v) const
- {
- size_t s = v.size();
- for (size_t i = 1; i < s; i++)
- {
- v[i - 1] -= 1;
- v[i] += 10;
- }
- }
- //数组乘整数
- lnum lnum::operator*(const int i) const
- {
- lnum r = "0";
- if (num.sign != 0)
- {
- r = *this;
- attr &rum = r.num;
- for (int &k : rum.vec)
- {
- k *= i;
- }
- Carry(rum.vec);
- r = Vec2Str(rum.vec, rum.sign, rum.dsize);
- }
- return r;
- }
- //输出字符串
- const string lnum::outPutStr() const
- {
- string str = num.str;
- const size_t &ds = num.dsize;
- if (precision < ds)
- {
- if (precision == 0)
- {
- str.erase(str.size() - ds - 1);
- }
- else
- {
- str.erase(str.size() - ds);
- }
- }
- return str;
- }
- /***********************************************************************/
- //数字属性
- void lnum::showinfo() const
- {
- std::cout << "正/负/零: " << num.sign << "\n"
- << "原始字符: " << num.str << "\n"
- << "数字元素: ";
- for (const int &i : num.vec)
- {
- std::cout << i << " ";
- }
- std::cout << std::endl;
- std::cout << "数字长度: " << num.nsize << "\n"
- << "小数位数: " << num.dsize << std::endl;
- }
- //(1)重载>
- const bool lnum::operator>(const lnum &l) const
- {
- bool f = true;
- const align agn = this->nAlign(l);
- const vecint &fst = agn.first,
- &sec = agn.second;
- const int tsgn = num.sign, &lsgn = l.num.sign;
- if (tsgn < lsgn)
- {
- f = false;
- }
- else if (tsgn == lsgn)
- {
- f = fst > sec;
- if (tsgn < 0)
- {
- f = !f;
- }
- }
- return f;
- }
- //(2)重载==
- const bool lnum::operator==(const lnum &l) const
- {
- const align agn = this->nAlign(l);
- const vecint &fst = agn.first,
- &sec = agn.second;
- return (num.sign == l.num.sign) && (fst == sec);
- }
- //(2.5)重载!=
- const bool lnum::operator!=(const lnum &l) const
- {
- return !(*this == l);
- }
- //(3)重载>=
- const bool lnum::operator>=(const lnum &l) const
- {
- return (*this == l || *this > l);
- }
- //(4)重载<
- const bool lnum::operator<(const lnum &l) const
- {
- return !(*this >= l);
- }
- //(5)重载<=
- const bool lnum::operator<=(const lnum &l) const
- {
- return (*this < l || *this == l);
- }
- //(6)重载+
- const lnum lnum::operator+(const lnum &l) const
- {
- lnum r = "0";
- const int &tsgn = num.sign, &lsgn = l.num.sign;
- if ((tsgn == 0 && lsgn != 0) || (tsgn != 0 && lsgn == 0))
- {
- r = (tsgn != 0) > (lsgn != 0) ? *this : l;
- }
- else if (*this != (-l))
- {
- int sgn = -1;
- const size_t &tds = num.dsize, &lds = l.num.dsize,
- &ds = tds > lds ? tds : lds;
- align agn = this->nAlign(l);
- vecint &fst = agn.first, &sec = agn.second, t = fst >= sec ? fst : sec;
- size_t s = fst.size();
- for (size_t i = 0; i < s; i++)
- {
- t[i] += ((tsgn * lsgn) * ((sec <= fst ? sec : fst)[i]));
- }
- if ((fst < sec && tsgn < lsgn) || (sec < fst && lsgn < tsgn) || (tsgn == lsgn && tsgn == 1))
- {
- sgn = 1;
- }
- if (tsgn!=lsgn)
- {
- Borrow(t);
- }
- Carry(t);
- attr &rum = r.num;
- rum.str = ClearStrZero(Vec2Str(t, sgn, ds));
- rum.vec = Str2Vec(rum.str);
- rum.nsize = rum.vec.size();
- rum.dsize = ds;
- rum.sign = sgn;
- }
- return r;
- }
- //(7)重载-,反转正负
- const lnum lnum::operator-() const
- {
- lnum r = *this;
- r.num.sign = -num.sign;
- r.num.str = Vec2Str(num.vec, -num.sign, num.dsize);
- return r;
- }
- //(8)重载-
- const lnum lnum::operator-(const lnum &l) const
- {
- lnum r;
- const int &tsgn = num.sign, &lsgn = l.num.sign;
- if (tsgn == 0 && lsgn != 0)
- {
- r = -l;
- }
- else if (lsgn == 0 && tsgn != 0)
- {
- r = *this;
- }
- else if (lsgn != 0 && tsgn != 0)
- {
- r = *this + (-l);
- }
- return r;
- }
- //(9)重载+=
- const lnum &lnum::operator+=(const lnum &l)
- {
- *this = *this + l;
- return *this;
- }
- //(10)重载++
- const lnum &lnum::operator++()
- {
- return *this += "1";
- }
- //(11)重载-=
- const lnum &lnum::operator-=(const lnum &l)
- {
- *this = *this - l;
- return *this;
- }
- //(12)重载--
- const lnum &lnum::operator--()
- {
- return *this -= "1";
- }
- //(13)前置++
- const lnum &operator++(lnum &l, const int i)
- {
- return ++l;
- }
- //(14)前置--
- const lnum &operator--(lnum &l, const int i)
- {
- return --l;
- }
- void lnum::setprecision(const size_t i)
- {
- lnum::precision = i;
- }
- ostream &operator<<(ostream &os, const lnum &l)
- {
- os << l.outPutStr();
- return os;
- }
- istream &operator>>(istream &is, lnum &l)
- {
- string inPutStr;
- (is >> inPutStr).get();
- l = inPutStr;
- return is;
- }
复制代码
=====================================================================
main.cpp
- #include "E:\Users\admin\Documents\VScode\Code\My Class\largenum\lnum.cpp"
- #include <ctime>
- int main(int argc, char const *argv[])
- {
- lnum::setprecision(3);
- lnum a, b;
- srand(time(NULL));
- char m[7], n[7];
- n[6] = m[6] = '\0';
- int k = 0;
- while (k != 10)
- {
- for (size_t i = 0; i < 6; i++)
- {
- m[i] = rand() % 9 + 48;
- n[i] = rand() % 9 + 48;
- }
- m[rand() % 2 + 2] = '.';
- n[rand() % 2 + 2] = '.';
- if (k % 2 == 0)
- {
- m[0] = '-';
- }
- if (k%3 == 0)
- {
- n[0] = '-';
- }
- a = m;
- b = n;
- std::cout << "第" << k << "组"
- << "\n"
- << "a = " << a << " "
- << "b = " << b << "\n--------------------------------------------------\n"
- << "a > b: " << std::boolalpha << (a > b) << "\n"
- << "a == b: " << (a == b) << "\n"
- << "a < b: " << (a < b) << "\n--------------------------------------------------------\n"
- << "a + b = " << (a + b) << "\n"
- << "a - b = " << (a - b) << "\n=======================================================\n";
- k++;
- }
-
- 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-yrdvjqxw.52e --stdout=Microsoft-MIEngine-Out-l05gzt3v.anm --stderr=Microsoft-MIEngine-Error-cyag0fjm.qse --pid=Microsoft-MIEngine-Pid-42rglrua.ou0 --dbgExe=D:\MinGW\bin\gdb.exe --interpreter=mi
第0组
a = -3.08 b = -38.58
--------------------------------------------------
a > b: true
a == b: false
a < b: false
--------------------------------------------------------
a + b = -41.66
a - b = 35.5
=======================================================
第1组
a = 407.56 b = 601.42
--------------------------------------------------
a > b: false
a == b: false
a < b: true
--------------------------------------------------------
a + b = 1008.98
a - b = -193.86
=======================================================
第2组
a = -6.366 b = 72.44
--------------------------------------------------
a > b: false
a == b: false
a < b: true
--------------------------------------------------------
a + b = 66.074
a - b = -78.806
=======================================================
第3组
a = 652.88 b = -1.731
--------------------------------------------------
a > b: true
a == b: false
a < b: false
--------------------------------------------------------
a + b = 651.149
a - b = 654.611
=======================================================
第4组
a = -1.467 b = 745.22
--------------------------------------------------
a > b: false
a == b: false
a < b: true
--------------------------------------------------------
a + b = 743.753
a - b = -746.687
=======================================================
第5组
a = 842.55 b = 63.016
--------------------------------------------------
a > b: true
a == b: false
a < b: false
--------------------------------------------------------
a + b = 905.566
a - b = 779.534
=======================================================
第6组
a = -46.87 b = -4.057
--------------------------------------------------
a > b: false
a == b: false
a < b: true
--------------------------------------------------------
a + b = -50.927
a - b = -42.813
=======================================================
第7组
a = 10.748 b = 752.88
--------------------------------------------------
a > b: false
a == b: false
a < b: true
--------------------------------------------------------
a + b = 763.628
a - b = -742.132
=======================================================
第8组
a = -1.506 b = 804.61
--------------------------------------------------
a > b: false
a == b: false
a < b: true
--------------------------------------------------------
a + b = 803.104
a - b = -806.116
=======================================================
第9组
a = 2.626 b = -6.542
--------------------------------------------------
a > b: true
a == b: false
a < b: false
--------------------------------------------------------
a + b = -3.916
a - b = 9.168
=======================================================
E:\Users\admin\Documents\VScode\Code> |
|