|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 bin554385863 于 2019-12-30 16:13 编辑
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
- #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; //符号
- bool iszero = true;
- 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
- lnum Borrow();
- //对齐
- const align AlignVec(const vector<int> &m, const vector<int> &n) const;
- //clear zero vec
- lnum &ClearZeroVec();
- //vec to str
- lnum &VecToStr();
- //iszero
- const bool IsZero(const lnum &l) const;
- 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;
- const lnum operator-() const;
- //+=
- const lnum &operator+=(const lnum &l);
- //++
- const lnum &operator++();
- //-=
- const lnum &operator-=(const lnum &l);
- //--
- const lnum &operator--();
- //odject++
- friend const lnum &operator++(lnum &l, const int i);
- //object--
- friend const lnum &operator--(lnum &l, const int i);
- //>>
- 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;
- size_t &ndps = n.dpsize, &npre = n.prec;
- 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'))
- {
-
- n.iszero = false;//iszero
- size_t s = nstr.size(), i = 0;
- if (str[0] == '-')
- {
- n.sign = -1;
- }
- if (int(str.find('.')) != -1)
- {
- ndps = str.size() - str.find('.') - 1;
- if (nstr[0] == '0')
- {
- for (; i < s; i++)
- {
- if (nstr[i] != '0')
- {
- break;
- }
- }
- if (i >= s - ndps)
- {
- nstr.erase(0, s - ndps - 1);
- }
- else if (i < s - ndps)
- {
- 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 (npre > ndps)
- {
- nstr.insert(nstr.end(), npre - ndps, '0');
- }
- else if (npre < ndps)
- {
- nstr.erase(nstr.size() - (ndps - npre));
- ndps = npre;
- }
- 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 t = num.str, &str = t;
- const size_t &prec = num.prec, &dpsize = num.dpsize;
- if (prec != 0 && str.size() != 1)
- {
- 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
- lnum lnum::Borrow()
- {
- vector<int> &v = num.vec;
- size_t s = v.size();
- for (size_t i = 1; i < s; i++)
- {
- v[i - 1] -= 1;
- v[i] += 10;
- }
- return *this;
- }
- //对齐
- 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;
- }
- //clear zero vec
- lnum &lnum::ClearZeroVec()
- {
- const size_t &prec = num.prec;
- vector<int> &v = num.vec;
-
- if (num.iszero)//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;
- }
- //iszero
- const bool lnum::IsZero(const lnum &l) const
- {
- return !((!num.iszero) || (!l.num.iszero));
- }
- //------------------------------------------------------------------------
- //设置精度
- 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"
- << std::boolalpha << "是否为零: " << num.iszero << "\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;
- lr.iszero = this->IsZero(l);
- const align &agn = AlignVec(num.vec, l.num.vec);
- const int &tsgn = num.sign, &lsgn = l.num.sign;
- const vector<int> &fst = agn.first, &sec = agn.second, &tvec = num.vec, &lvec = l.num.vec;
- lr.prec = num.prec;
- lr.dpsize = (num.dpsize >= l.num.dpsize ? num.dpsize : l.num.dpsize);
- size_t s = (fst.size() <= sec.size() ? fst.size() : sec.size());
- lr.vec = (fst >= sec ? fst : sec);
- for (size_t i = 0; i < s; i++)
- {
- lr.vec[i] += (tsgn * lsgn) * ((sec <= fst ? sec : fst)[i]);
- }
- if ((fst > sec && tsgn < lsgn) || (fst < sec && tsgn > lsgn) || (tsgn == -1 && lsgn == -1))
- {
- lr.sign = -1;
- }
- if (tsgn * lsgn == -1)
- {
- r.Borrow();
- }
- r.Carry().ClearZeroVec().VecToStr();
- lr.nsize = lr.vec.size();
- return r;
- }
- //符号取反
- const lnum lnum::operator-() const
- {
- const vector<int> &tvec = num.vec;
- lnum r = *this;
- if (num.iszero == false)//(tvec != vector<int>(tvec.size(), 0))
- {
- r.num.sign = -num.sign;
- }
- return r;
- }
- //-
- const lnum lnum::operator-(const lnum &l) const
- {
- lnum r;
- r.num.iszero = this->IsZero(l);
- if (l.num.iszero == false)//(l.num.vec != vector<int>(1, 0))
- {
- r = *this + (-l);
- }
- else
- {
- r = *this;
- }
- return r;
- }
- //+=
- const lnum &lnum::operator+=(const lnum &l)
- {
- *this = *this + l;
- return *this;
- }
- //前置++
- const lnum &lnum::operator++()
- {
- return *this += "1";
- }
- //-=
- const lnum &lnum::operator-=(const lnum &l)
- {
- *this = *this - l;
- return *this;
- }
- //前置--
- const lnum &lnum::operator--()
- {
- return *this -= "1";
- }
- //后置++
- const lnum &operator++(lnum &l, const int i)
- {
- return ++l;
- }
- //后置--
- const lnum &operator--(lnum &l, const int i)
- {
- return --l;
- }
- //>>
- 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;
- }
复制代码
test.cpp
- #include "E:\Users\admin\Documents\VScode\Code\My Class\shape.cpp\lnum\lnum.cpp"
- #include <ctime>
- #include <cmath>
- int main(int argc, char const *argv[])
- {
- int s = 0;
- lnum::SetPrecision(6);
- lnum a, b;
- char n[9], m[9];
- n[8] = m[8] = '\0';
- srand(time(NULL));
- while (s != 12)
- {
- for (size_t i = 0; i < 8; i++)
- {
- n[i] = rand() % 9 + 48;
- m[i] = rand() % 9 + 48;
- }
- n[rand() % 6 + 1] = '.';
- m[rand() % 6 + 1] = '.';
- if (s % 2 == 0)
- {
- n[0] = '-';
- }
- if (s % 3 == 0)
- {
- m[0] = '-';
- }
- a = m;
- b = n;
- std::cout << "第" << s << "组" << std::endl;
- std::cout << a << " - " << b << " = " << (a - b) << "\n"
- << a << " + " << b << " = " << (a + b) << "\n\n"
- << std::boolalpha
- << a << " > " << b << ": " << (a > b) << "\n\n"
- << a << " == " << b << ": " << (a == b) << "\n\n"
- << a << " < " << b << ": " << (a < b) << "\n\n"
- << a << " >= " << b << ": " << (a >= b) << "\n\n"
- << a << " <= " << b << ": " << (a <= b) << "\n"
- << "------------------------------------------------"
- << "\n\n";
- s++;
- }
- 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-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> |
|