字符串计算第二版
本帖最后由 bin554385863 于 2020-1-3 16:15 编辑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
{
typedef vector<int> vecint;
struct attr
{
string str;
int sign;
vecint vec;
size_t nsize, dsize;
};
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 getDpsize(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;
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;
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 = 3;
#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(),
getDpsize(n.str)};
return n;
}
//(2)判断是否有效的数字字符串
const bool lnum::IsNumStr(const string &s) const
{
bool f = true;
string str = s;
if (str == '-')
{
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 == '-')
{
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 == '-')
{
str.erase(0, 1);
}
size_t i = 0;
if (int(s.find('.')) == -1)
{
size_t sz = str.size();
while (i != sz)
{
if (str != '0')
{
break;
}
i++;
}
if (i == sz)
{
str.erase(0, i - 1);
}
else
{
str.erase(0, i);
}
}
else
{
i = 0;
while (str != '.')
{
if (str != '0')
{
break;
}
i++;
}
if (i == str.find('.'))
{
str.erase(0, i - 1);
}
else
{
str.erase(0, i);
}
i = str.size() - 1;
while (str != '.')
{
if (str != '0')
{
break;
}
i--;
}
if (i == str.find('.'))
{
str.erase(i);
}
else if (i < str.size() - 1)
{
str.erase(i + 1);
}
}
if (s == '-')
{
str.insert(0, 1, '-');
}
}
return str;
}
//(5)获取正负符号
const int lnum::getSign(const string &s) const
{
int sgn = 0;
if (s != "0")
{
sgn = s == '-' ? -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 == '-')
{
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::getDpsize(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;
v = t % 10;
v += t / 10;
}
}
//借一
void lnum::Borrow(vecint &v) const
{
size_t s = v.size();
for (size_t i = 1; i < s; i++)
{
v -= 1;
v += 10;
}
}
//数组乘整数
lnum lnum::operator*(const int i) const
{
lnum t = *this, r = "0";
if (num.sign != 0)
{
attr &rum = t.num;
for (int &k : rum.vec)
{
k *= i;
}
Carry(rum.vec);
r = ClearStrZero(Vec2Str(rum.vec, rum.sign, rum.dsize));
}
return r;
}
/***********************************************************************/
//数字属性
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 += ((tsgn * lsgn) * ((sec <= fst ? sec : fst)));
}
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;
}
void lnum::setprecision(const size_t i)
{
lnum::precision = i;
}
ostream &operator<<(ostream &os, const lnum &l)
{
os << l.num.str;
return os;
}
istream &operator>>(istream &is, lnum &l)
{
string inputstr;
(is >> inputstr).get();
l = inputstr;
return is;
}
=======================================================================
#include "E:\Users\admin\Documents\VScode\Code\My Class\largenum\lnum.cpp"
int main(int argc, char const *argv[])
{
lnum a = "-5.000009", b = "6000";
std::cout << (a + b) << std::endl;
(a + b).showinfo();
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-tmgi4wns.nfx --stdout=Microsoft-MIEngine-Out-sz504ytr.rqz --stderr=Microsoft-MIEngine-Error-ni2x4gi1.12t --pid=Microsoft-MIEngine-Pid-mtm4v2ay.ggn --dbgExe=D:\MinGW\bin\gdb.exe --interpreter=mi
5994.999991
正/负/零: 1
原始字符: 5994.999991
数字元素: 5 9 9 4 9 9 9 9 9 1
数字长度: 10
小数位数: 6
E:\Users\admin\Documents\VScode\Code> __优化代码
__添加算法
__实现精度输出
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 == '-')
{
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 == '-')
{
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 == '-')
{
str.erase(0, 1);
}
size_t i = 0;
if (int(s.find('.')) == -1)
{
size_t sz = str.size();
while (i != sz)
{
if (str != '0')
{
break;
}
i++;
}
if (i == sz)
{
str.erase(0, i - 1);
}
else
{
str.erase(0, i);
}
}
else
{
i = 0;
while (str != '.')
{
if (str != '0')
{
break;
}
i++;
}
if (i == str.find('.'))
{
str.erase(0, i - 1);
}
else
{
str.erase(0, i);
}
i = str.size() - 1;
while (str != '.')
{
if (str != '0')
{
break;
}
i--;
}
if (i == str.find('.'))
{
str.erase(i);
}
else if (i < str.size() - 1)
{
str.erase(i + 1);
}
}
if (s == '-')
{
str.insert(0, 1, '-');
}
}
return str;
}
//(5)获取正负符号
const int lnum::getSign(const string &s) const
{
int sgn = 0;
if (s != "0")
{
sgn = s == '-' ? -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 == '-')
{
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;
v = t % 10;
v += t / 10;
}
}
//借一
void lnum::Borrow(vecint &v) const
{
size_t s = v.size();
for (size_t i = 1; i < s; i++)
{
v -= 1;
v += 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 += ((tsgn * lsgn) * ((sec <= fst ? sec : fst)));
}
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, n;
n = m = '\0';
int k = 0;
while (k != 10)
{
for (size_t i = 0; i < 6; i++)
{
m = rand() % 9 + 48;
n = rand() % 9 + 48;
}
m = '.';
n = '.';
if (k % 2 == 0)
{
m = '-';
}
if (k%3 == 0)
{
n = '-';
}
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.08b = -38.58
--------------------------------------------------
a >b: true
a == b: false
a <b: false
--------------------------------------------------------
a +b = -41.66
a -b = 35.5
=======================================================
第1组
a = 407.56b = 601.42
--------------------------------------------------
a >b: false
a == b: false
a <b: true
--------------------------------------------------------
a +b = 1008.98
a -b = -193.86
=======================================================
第2组
a = -6.366b = 72.44
--------------------------------------------------
a >b: false
a == b: false
a <b: true
--------------------------------------------------------
a +b = 66.074
a -b = -78.806
=======================================================
第3组
a = 652.88b = -1.731
--------------------------------------------------
a >b: true
a == b: false
a <b: false
--------------------------------------------------------
a +b = 651.149
a -b = 654.611
=======================================================
第4组
a = -1.467b = 745.22
--------------------------------------------------
a >b: false
a == b: false
a <b: true
--------------------------------------------------------
a +b = 743.753
a -b = -746.687
=======================================================
第5组
a = 842.55b = 63.016
--------------------------------------------------
a >b: true
a == b: false
a <b: false
--------------------------------------------------------
a +b = 905.566
a -b = 779.534
=======================================================
第6组
a = -46.87b = -4.057
--------------------------------------------------
a >b: false
a == b: false
a <b: true
--------------------------------------------------------
a +b = -50.927
a -b = -42.813
=======================================================
第7组
a = 10.748b = 752.88
--------------------------------------------------
a >b: false
a == b: false
a <b: true
--------------------------------------------------------
a +b = 763.628
a -b = -742.132
=======================================================
第8组
a = -1.506b = 804.61
--------------------------------------------------
a >b: false
a == b: false
a <b: true
--------------------------------------------------------
a +b = 803.104
a -b = -806.116
=======================================================
第9组
a = 2.626b = -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>
优化代码
本帖最后由 bin554385863 于 2020-1-5 18:06 编辑lnum.h
/*
(1)原始数字字符串->清除无效的零->转换数组,提取信息(小数位数,整数位数,是否为零);
(2)整体对齐->比较大小,设计加/减法;
(3)小数位对齐->设计数组乘整数->设计数组乘数组->实现对象乘法;
(补充)实现满十进一,退一借十;
*/
#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 ndata
{
int sign;
string nstr;
vector<int> nvec;
size_t isize, dsize;
};
struct align
{
vector<int> first, second;
};
private:
static size_t pre;
ndata data;
//(0)判断是否含有小数点
const bool hasDecPoint(const string &s) const;
//(1)判断字符串是否有效
const bool isInvalidStr(const string &s) const;
//(2)判断字符串元素是否全为零
const bool isStrElemAllZero(const string &s) const;
//(3)清除无效的零
const string clearInvalidZero(const string &s) const;
//(4)转换数组
const vector<int> strToVec(const string &s) const;
//(-4)转换字符串
const string vecToStr(const vector<int> &vint, int sgn, size_t dsz) const;
//(5)提取信息
const ndata getInfo(const string &s) const;
//(6)小数位对齐
align dAlign(const lnum &l) const;
//(7)整体对齐
align wAlign(const lnum &l) const;
//(8)满十进一
void carry(vector<int> &v) const;
//(9)借一补十
void borrow(vector<int> &v) const;
public:
lnum(const char *cstr = "0") : data(getInfo(cstr)){}
lnum(const string &s):data(getInfo(s)){}
void showinfo() const;
//(1)>号
const bool operator>(const lnum &l) const;
//(2)==
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;
//(5)!=
const bool operator!=(const lnum &l) const;
//(6)+
const lnum operator+(const lnum &l) const;
//(7)-反转正负
const lnum operator-() const;
//(F)<<
friend ostream &operator<<(ostream &os, const lnum &l);
};
#endif
lnum.cpp
#include "E:\Users\admin\Documents\VScode\Code\My Class\lnum\lnum.h"
//(0)判断是否含有小数点
const bool lnum::hasDecPoint(const string &s) const
{
return int(s.find('.')) > -1 ? true : false;
}
//(1)判断字符串是否有效
const bool lnum::isInvalidStr(const string &s) const
{
bool f = true;
if (s != '-'&&!isdigit(s))
{
f = false;
}
else
{
string str = s;
if (str == '-')
{
str.erase(0, 1);
}
if (!hasDecPoint(str))
{
for(char c:str)
{
if (!isdigit(c))
{
f = false;
break;
}
}
}
else
{
size_t dpinx = str.find('.');
f = (dpinx == 0) || (dpinx ==(str.size()- 1)) || (dpinx != str.rfind('.')) ? false : true;
str.erase(dpinx, 1);
for (char c : str)
{
if (!isdigit(c))
{
f = false;
break;
}
}
}
}
return f;
}
//(2)判断字符串元素是否全为零
const bool lnum::isStrElemAllZero(const string &s) const
{
string str = s;
str == '-' ? str.erase(0, 1) : str;
hasDecPoint(str) > false ? str.erase(str.find('.'), 1) : str;
return str == string(str.size(), '0') ? true : false;
}
//(3)清除无效的零
const string lnum::clearInvalidZero(const string &s) const
{
string str = s;
if (isInvalidStr(s))
{
size_t i = 0;
if (str == '-')
{
str.erase(0, 1);
}
if (!hasDecPoint(s))
{
size_t sz = str.size();
while (i != sz)
{
if (str != '0')
{
break;
}
i++;
}
if (i == sz)
{
str.erase(0, i - 1);
}
else if (i > 0)
{
str.erase(0, i);
}
}
else
{
i = 0;
while (str != '.')
{
if (str != '0')
{
break;
}
i++;
}
if (i == str.find('.'))
{
str.erase(0, i - 1);
}
else if (i > 0)
{
str.erase(0, i);
}
i = str.size() - 1;
while (str != '.')
{
if (str != '0')
{
break;
}
i--;
}
if (i == str.find('.'))
{
str.erase(i);
}
else if (i < str.size() - 1)
{
str.erase(i + 1);
}
}
if (s == '-' && str != "0")
{
str.insert(0, 1, '-');
}
}
return str;
}
//(4)转换数组
const vector<int> lnum::strToVec(const string &s) const
{
vector<int> vint;
string str = s;
str == '-' ? str.erase(0, 1) : str;
hasDecPoint(str) > false ? str.erase(str.find('.'), 1) : str;
for (char c : str)
{
vint.push_back(c - 48);
}
return vint;
}
//(-4)转换字符串
const string lnum::vecToStr(const vector<int> &vint, int sgn, size_t dsz) const
{
string str;
for (int i : vint)
{
str.push_back(i + 48);
}
if (str != "0")
{
dsz == 0 ? str : str.insert(str.size() - dsz, 1, '.');
sgn == -1 ? str.insert(0, 1, '-') : str;
}
return str;
}
//(5)提取信息
const lnum::ndata lnum::getInfo(const string &s) const
{
ndata ndt = {0, "0", {0}, 1, 0};
if (isInvalidStr(s))
{
ndt.nstr = clearInvalidZero(s);
ndt.sign = ndt.nstr != "0" ? (ndt.nstr == '-' ? -1 : 1) : 0;
ndt.dsize = hasDecPoint(ndt.nstr) || false ? ndt.nstr.size() - ndt.nstr.find('.') - 1 : 0;
ndt.nvec = strToVec(ndt.nstr);
ndt.isize = ndt.nvec.size() - ndt.dsize;
}
return ndt;
}
//(6)小数位对齐
lnum::align lnum::dAlign(const lnum &l) const
{
align agn;
vector<int> &f = agn.first, &s = agn.second;
f = data.nvec;
s = l.data.nvec;
const size_t &fds = data.dsize, &sds = l.data.dsize;
fds > sds ? s.insert(s.end(), fds - sds, 0) : f.insert(f.end(), sds - fds, 0);
return agn;
}
//(7)整体对齐
lnum::align lnum::wAlign(const lnum &l) const
{
align &&agn = this->dAlign(l);
vector<int> &f = agn.first, &s = agn.second;
const size_t &fws = data.isize, &sws = l.data.isize;
fws > sws ? s.insert(s.begin(), fws - sws, 0) : f.insert(f.begin(), sws - fws, 0);
return agn;
}
//(8)满十进一
void lnum::carry(vector<int> &v) const
{
v.insert(v.begin(), 1, 0);
const size_t s = v.size();
for (size_t i = s - 1; i != 0; i--)
{
int t = v;
v = t % 10;
v += t / 10;
}
if (v == 0)
{
v.erase(v.begin(), v.begin() + 1);
}
}
//(9)借一补十
void lnum::borrow(vector<int> &v) const
{
const size_t s = v.size();
for (size_t i = 1; i < s; i++)
{
v -= 1;
v += 10;
}
}
//==========================================================================
//(0)显示信息
void lnum::showinfo() const
{
std::cout << "正/负/零: " << data.sign << "\n"
<< "原始数字: " << data.nstr << "\n"
<< "数组元素: ";
for (int i : data.nvec)
{
std::cout << i << " ";
}
std::cout << std::endl;
std::cout << "整数位数: " << data.isize << "\n"
<< "小数位数: " << data.dsize << std::endl;
}
//(1)>号
const bool lnum::operator>(const lnum &l) const
{
bool f = true;
const int &tsgn = data.sign, &lsgn = l.data.sign;
if (tsgn < lsgn)
{
f = false;
}
else if (tsgn == lsgn)
{
const align &agn = this->wAlign(l);
f = agn.first > agn.second;
if (tsgn == -1)
{
f = !f;
}
}
return f;
}
//(2)==
const bool lnum::operator==(const lnum &l) const
{
return (data.sign == l.data.sign) && (data.nvec == l.data.nvec);
}
//(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);
}
//(5.5)!=
const bool lnum::operator!=(const lnum &l) const
{
return !(*this == l);
}
//(6)+
const lnum lnum::operator+(const lnum &l) const
{
lnum r;
if (*this != (-l))
{
align agn = this->wAlign(l);
vector<int> &fst = agn.first,
&sec = agn.second,
&greater = fst >= sec ? fst : sec,
&less = sec <= fst ? sec : fst;
const int &tsgn = data.sign,
&lsgn = l.data.sign;
const size_t &sz = fst.size();
for (size_t i = 0; i < sz; i++)
{
greater += (lsgn * tsgn) * less;
}
int sgn = 1;
if (tsgn == lsgn)
{
sgn = (tsgn == 0) > (tsgn == -1) ? 0 : -1;
}
else if (tsgn != lsgn)
{
sgn = ((greater == fst && tsgn < lsgn) || (less == fst && tsgn > lsgn)) || false ? -1 : sgn;
}
if (tsgn * lsgn == -1)
{
borrow(greater);
}
carry(greater);
size_t dsz = data.dsize >= l.data.dsize ? data.dsize : l.data.dsize;
string str = vecToStr(greater, sgn, dsz);
r = str;
}
return r;
}
//(7)-反转正负
const lnum lnum::operator-() const
{
lnum r = *this;
if (data.sign != 0)
{
r.data.sign = -data.sign;
r.data.nstr = vecToStr(data.nvec, -data.sign, data.dsize);
}
return r;
}
//(F)<<
ostream &operator<<(ostream &os, const lnum &l)
{
os << l.data.nstr;
return os;
} 本帖最后由 bin554385863 于 2020-1-5 20:23 编辑
继续优化
lnum.h
/*
(1)原始数字字符串->清除无效的零->转换数组,提取信息(小数位数,整数位数,是否为零);
(2)整体对齐->比较大小,设计加/减法;
(3)小数位对齐->设计数组乘整数->设计数组乘数组->实现对象乘法;
(补充)实现满十进一,退一借十;
*/
#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 ndata
{
int sign;
string nstr;
vector<int> nvec;
size_t isize, dsize;
};
struct align
{
vector<int> first, second;
};
private:
static size_t pre;
ndata data;
//(0)判断是否含有小数点
const bool hasDecPoint(const string &s) const;
//(1)判断字符串是否有效
const bool isInvalidStr(const string &s) const;
//(2)判断字符串元素是否全为零
const bool isStrElemAllZero(const string &s) const;
//(3)清除无效的零
const string clearInvalidZero(const string &s) const;
//(4)转换数组
const vector<int> strToVec(const string &s) const;
//(-4)转换字符串
const string vecToStr(const vector<int> &vint, int sgn, size_t dsz) const;
//(5)提取信息
const ndata getInfo(const string &s) const;
//(6)小数位对齐
align dAlign(const lnum &l) const;
//(7)整体对齐
align wAlign(const lnum &l) const;
//(8)满十进一
void carry(vector<int> &v) const;
//(9)借一补十
void borrow(vector<int> &v) const;
//(10)截断输出
const string outPut() const;
public:
lnum(const char *cstr = "0") : data(getInfo(cstr)){}
lnum(const string &s):data(getInfo(s)){}
void showinfo() const;
static void setprecision(const size_t p);
//(1)>号
const bool operator>(const lnum &l) const;
//(2)==
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;
//(5)!=
const bool operator!=(const lnum &l) const;
//(6)+
const lnum operator+(const lnum &l) const;
//(7)-反转正负
const lnum operator-() const;
//(F)<<
friend ostream &operator<<(ostream &os, const lnum &l);
//(F)>>
friend istream &operator>>(istream &is, lnum &l);
};
size_t lnum::pre = 6;
#endif
lnum.cpp
#include "E:\Users\admin\Documents\VScode\Code\My Class\lnum\lnum.h"
//(0)判断是否含有小数点
const bool lnum::hasDecPoint(const string &s) const
{
return int(s.find('.')) > -1 ? true : false;
}
//(1)判断字符串是否有效
const bool lnum::isInvalidStr(const string &s) const
{
bool f = true;
string str = s;
if (str == '-')
{
str.erase(0, 1);
}
if (!hasDecPoint(str))
{
for (char c : str)
{
if (!isdigit(c))
{
f = false;
break;
}
}
}
else
{
size_t dpinx = str.find('.');
f = (dpinx == 0) || (dpinx == (str.size() - 1)) || (dpinx != str.rfind('.')) ? false : true;
str.erase(dpinx, 1);
for (char c : str)
{
if (!isdigit(c))
{
f = false;
break;
}
}
}
return f;
}
//(2)判断字符串元素是否全为零
const bool lnum::isStrElemAllZero(const string &s) const
{
string str = s;
str == '-' ? str.erase(0, 1) : str;
hasDecPoint(str) || false ? str.erase(str.find('.'), 1) : str;
return str == string(str.size(), '0') ? true : false;
}
//(3)清除无效的零
const string lnum::clearInvalidZero(const string &s) const
{
string str = s;
if (isInvalidStr(s))
{
size_t i = 0;
if (str == '-')
{
str.erase(0, 1);
}
if (!hasDecPoint(s))
{
size_t sz = str.size();
while (i != sz)
{
if (str != '0')
{
break;
}
i++;
}
if (i == sz)
{
str.erase(0, i - 1);
}
else if (i > 0)
{
str.erase(0, i);
}
}
else
{
i = 0;
while (str != '.')
{
if (str != '0')
{
break;
}
i++;
}
if (i == str.find('.'))
{
str.erase(0, i - 1);
}
else if (i > 0)
{
str.erase(0, i);
}
i = str.size() - 1;
while (str != '.')
{
if (str != '0')
{
break;
}
i--;
}
if (i == str.find('.'))
{
str.erase(i);
}
else if (i < str.size() - 1)
{
str.erase(i + 1);
}
}
if (s == '-' && str != "0")
{
str.insert(0, 1, '-');
}
}
return str;
}
//(4)转换数组
const vector<int> lnum::strToVec(const string &s) const
{
vector<int> vint;
string str = s;
str == '-' ? str.erase(0, 1) : str;
hasDecPoint(str) > false ? str.erase(str.find('.'), 1) : str;
for (char c : str)
{
vint.push_back(c - 48);
}
return vint;
}
//(-4)转换字符串
const string lnum::vecToStr(const vector<int> &vint, int sgn, size_t dsz) const
{
string str;
for (int i : vint)
{
str.push_back(i + 48);
}
if (str != "0")
{
dsz == 0 ? str : str.insert(str.size() - dsz, 1, '.');
sgn == -1 ? str.insert(0, 1, '-') : str;
}
return str;
}
//(5)提取信息
const lnum::ndata lnum::getInfo(const string &s) const
{
ndata ndt = {0, "0", {0}, 1, 0};
if (isInvalidStr(s))
{
ndt.nstr = clearInvalidZero(s);
ndt.sign = ndt.nstr != "0" ? (ndt.nstr == '-' ? -1 : 1) : 0;
ndt.dsize = hasDecPoint(ndt.nstr) || false ? ndt.nstr.size() - ndt.nstr.find('.') - 1 : 0;
ndt.nvec = strToVec(ndt.nstr);
ndt.isize = ndt.nvec.size() - ndt.dsize;
}
return ndt;
}
//(6)小数位对齐
lnum::align lnum::dAlign(const lnum &l) const
{
align agn;
vector<int> &f = agn.first, &s = agn.second;
f = data.nvec;
s = l.data.nvec;
const size_t &fds = data.dsize, &sds = l.data.dsize;
fds > sds ? s.insert(s.end(), fds - sds, 0) : f.insert(f.end(), sds - fds, 0);
return agn;
}
//(7)整体对齐
lnum::align lnum::wAlign(const lnum &l) const
{
align &&agn = this->dAlign(l);
vector<int> &f = agn.first, &s = agn.second;
const size_t &fws = data.isize, &sws = l.data.isize;
fws > sws ? s.insert(s.begin(), fws - sws, 0) : f.insert(f.begin(), sws - fws, 0);
return agn;
}
//(8)满十进一
void lnum::carry(vector<int> &v) const
{
v.insert(v.begin(), 1, 0);
const size_t s = v.size();
for (size_t i = s - 1; i != 0; i--)
{
int t = v;
v = t % 10;
v += t / 10;
}
if (v == 0)
{
v.erase(v.begin(), v.begin() + 1);
}
}
//(9)借一补十
void lnum::borrow(vector<int> &v) const
{
const size_t s = v.size();
for (size_t i = 1; i < s; i++)
{
v -= 1;
v += 10;
}
}
//(10)截断输出
const string lnum::outPut() const
{
const size_t &tds = data.dsize;
string str = data.nstr;
if (pre == 0)
{
if(tds != 0)
{
str.erase(str.find('.'));
}
}
else
{
if (tds > pre)
{
str.erase(str.size() - (tds - pre));
}
}
return str;
}
//==========================================================================
//(0)显示信息
void lnum::showinfo() const
{
std::cout << "正/负/零: " << data.sign << "\n"
<< "原始数字: " << data.nstr << "\n"
<< "数组元素: ";
for (int i : data.nvec)
{
std::cout << i << " ";
}
std::cout << std::endl;
std::cout << "整数位数: " << data.isize << "\n"
<< "小数位数: " << data.dsize << std::endl;
}
void lnum::setprecision(const size_t p)
{
pre = p;
}
//(1)>号
const bool lnum::operator>(const lnum &l) const
{
bool f = true;
const int &tsgn = data.sign, &lsgn = l.data.sign;
if (tsgn < lsgn)
{
f = false;
}
else if (tsgn == lsgn)
{
const align &agn = this->wAlign(l);
f = agn.first > agn.second;
if (tsgn == -1)
{
f = !f;
}
}
return f;
}
//(2)==
const bool lnum::operator==(const lnum &l) const
{
return (data.sign == l.data.sign) && (data.nvec == l.data.nvec);
}
//(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);
}
//(5.5)!=
const bool lnum::operator!=(const lnum &l) const
{
return !(*this == l);
}
//(6)+
const lnum lnum::operator+(const lnum &l) const
{
lnum r;
if (*this != (-l))
{
align agn = this->wAlign(l);
vector<int> &fst = agn.first,
&sec = agn.second,
&greater = fst >= sec ? fst : sec,
&less = sec <= fst ? sec : fst;
const int &tsgn = data.sign,
&lsgn = l.data.sign;
const size_t &sz = fst.size();
for (size_t i = 0; i < sz; i++)
{
greater += (lsgn * tsgn) * less;
}
int sgn = 1;
if (tsgn == lsgn)
{
sgn = tsgn;
}
else if (tsgn != lsgn)
{
sgn = ((greater == fst && tsgn < lsgn) || (less == fst && tsgn > lsgn)) || false ? -1 : sgn;
}
if (tsgn * lsgn == -1)
{
borrow(greater);
}
carry(greater);
size_t dsz = data.dsize >= l.data.dsize ? data.dsize : l.data.dsize;
//string str = vecToStr(greater, sgn, dsz);
r = vecToStr(greater, sgn, dsz);
}
return r;
}
//(7)-反转正负
const lnum lnum::operator-() const
{
lnum r = *this;
if (data.sign != 0)
{
r.data.sign = -data.sign;
r.data.nstr = vecToStr(data.nvec, -data.sign, data.dsize);
}
return r;
}
//(F)<<
ostream &operator<<(ostream &os, const lnum &l)
{
os << l.outPut();
return os;
}
//(F)>>
istream &operator>>(istream &is, lnum &l)
{
string str;
(std::cin >> str).get();
l = str;
return is;
} 添加减法
const lnum operator-(const lnum &l) const;
const lnum lnum::operator-(const lnum &l) const
{
return *this + (-l);
}
test.cpp
#include "E:\Users\admin\Documents\VScode\Code\My Class\lnum\lnum.cpp"
#include <ctime>
#include <cmath>
int main(int argc, char const *argv[])
{
lnum a = "1", b;
while ((a + b) != "0")
{
std::cin >> a >> b;
std::cout << "a - b = " << (a - b) << "\n"
<< "a + b = " << (a + b) << "\n==========================\n";
}
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-x4qpcw2n.sc2 --stdout=Microsoft-MIEngine-Out-pmiyg52x.pko --stderr=Microsoft-MIEngine-Error-ycnrwdt4.obr --pid=Microsoft-MIEngine-Pid-5gacmwbw.dbc --dbgExe=D:\MinGW\bin\gdb.exe --interpreter=mi
123
654
a - b = -531
a + b = 777
==========================
999
999
a - b = 0
a + b = 1998
==========================
987654321
123456789
a - b = 864197532
a + b = 1111111110
==========================
-99
999
a - b = -1098
a + b = 900
==========================
999
-99
a - b = 1098
a + b = 900
==========================
-5555
-9999
a - b = 4444
a + b = -15554
==========================
2
0.123654
a - b = 1.876346
a + b = 2.123654
==========================
0.123456789
0.000000005
a - b = 0.123456
a + b = 0.123456
==========================
0.0006
0.0005
a - b = 0.0001
a + b = 0.0011
==========================
-0.005
0.00004
a - b = -0.00504
a + b = -0.00496
==========================
1
-0.00005
a - b = 1.00005
a + b = 0.99995
==========================
-99999
-0.0006
a - b = -99998.9994
a + b = -99999.0006
==========================
-987
987
a - b = -1974
a + b = 0
==========================
E:\Users\admin\Documents\VScode\Code> bin554385863 发表于 2020-1-5 20:25
添加减法
const lnum operator-(const lnum &l) const;
添加
+=
-=
++
--
//(8)+=
const lnum &operator+=(const lnum &l);
//(9)++
const lnum &operator++(const int i);
//(10)-=
const lnum &operator-=(const lnum &l);
//(11)--
const lnum &operator--(const int i);
//(8)+=
const lnum &lnum::operator+=(const lnum &l)
{
return *this = *this + l;
}
//(9)++
const lnum &lnum::operator++(const int i)
{
return *this = *this + "1";
}
//(10)-=
const lnum &lnum::operator-=(const lnum &l)
{
return *this = *this + (-l);
}
//(11)--
const lnum &lnum::operator--(const int i)
{
return *this = *this + "-1";
} 本帖最后由 bin554385863 于 2020-1-6 04:30 编辑
已经实现
数字字符串加减乘三种运算和五种比较运算,
lnum.cpp
/*
(1)原始数字字符串->清除无效的零->转换数组,提取信息(小数位数,整数位数,是否为零);
(2)整体对齐->比较大小,设计加/减法;
(3)小数位对齐->设计数组乘整数->设计数组乘数组->实现对象乘法;
(补充)实现满十进一,退一借十;
*/
#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 ndata
{
int sign;
string nstr;
vector<int> nvec;
size_t isize, dsize;
};
struct align
{
vector<int> first, second;
};
private:
static size_t pre;
ndata data;
//(0)判断是否含有小数点
const bool hasDecPoint(const string &s) const;
//(1)判断字符串是否有效
const bool isInvalidStr(const string &s) const;
//(2)判断字符串元素是否全为零
const bool isStrElemAllZero(const string &s) const;
//(3)清除无效的零
const string clearInvalidZero(const string &s) const;
//(4)转换数组
const vector<int> strToVec(const string &s) const;
//(-4)转换字符串
const string vecToStr(const vector<int> &vint, int sgn, size_t dsz) const;
//(5)提取信息
const ndata getInfo(const string &s) const;
//(6)小数位对齐
align dAlign(const lnum &l) const;
//(7)整体对齐
align wAlign(const lnum &l) const;
//(8)满十进一
void carry(vector<int> &v) const;
//(9)借一补十
void borrow(vector<int> &v) const;
//(10)输出设置
const string setPrint() const;
//(11)lnum*n
const lnum operator*(const int &n) const;
public:
lnum(const char *cstr = "0") : data(getInfo(cstr))
{
}
lnum(const string &s):data(getInfo(s)){}
void showinfo() const;
static void setprecision(const size_t p);
//(1)>号
const bool operator>(const lnum &l) const;
//(2)==
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;
//(5)!=
const bool operator!=(const lnum &l) const;
//(6)+
const lnum operator+(const lnum &l) const;
//(7)-反转正负
const lnum operator-() const;
//(7.5)-
const lnum operator-(const lnum &l) const;
//(8)+=
const lnum &operator+=(const lnum &l);
//(9)++
const lnum &operator++(const int i);
//(10)-=
const lnum &operator-=(const lnum &l);
//(11)--
const lnum &operator--(const int i);
//(12)lnum*lnum
const lnum operator*(const lnum &l) const;
//(F)<<
friend ostream &operator<<(ostream &os, const lnum &l);
//(F)>>
friend istream &operator>>(istream &is, lnum &l);
};
size_t lnum::pre = 6;
#endif
====================================================
lnum.cpp
#include "E:\Users\admin\Documents\VScode\Code\My Class\lnum\lnum.h"
//(0)判断是否含有小数点
const bool lnum::hasDecPoint(const string &s) const
{
return int(s.find('.')) > -1 ? true : false;
}
//(1)判断字符串是否有效
const bool lnum::isInvalidStr(const string &s) const
{
bool f = true;
string str = s;
if (str == '-')
{
str.erase(0, 1);
}
if (!hasDecPoint(str))
{
for (char c : str)
{
if (!isdigit(c))
{
f = false;
break;
}
}
}
else
{
size_t dpinx = str.find('.');
f = (dpinx == 0) || (dpinx == (str.size() - 1)) || (dpinx != str.rfind('.')) ? false : true;
str.erase(dpinx, 1);
for (char c : str)
{
if (!isdigit(c))
{
f = false;
break;
}
}
}
return f;
}
//(2)判断字符串元素是否全为零
const bool lnum::isStrElemAllZero(const string &s) const
{
string str = s;
str == '-' ? str.erase(0, 1) : str;
hasDecPoint(str) || false ? str.erase(str.find('.'), 1) : str;
return str == string(str.size(), '0') ? true : false;
}
//(3)清除无效的零
const string lnum::clearInvalidZero(const string &s) const
{
string str = s;
if (isInvalidStr(s))
{
size_t i = 0;
if (str == '-')
{
str.erase(0, 1);
}
if (!hasDecPoint(s))
{
size_t sz = str.size();
while (i != sz)
{
if (str != '0')
{
break;
}
i++;
}
if (i == sz)
{
str.erase(0, i - 1);
}
else if (i > 0)
{
str.erase(0, i);
}
}
else
{
i = 0;
while (str != '.')
{
if (str != '0')
{
break;
}
i++;
}
if (i == str.find('.'))
{
str.erase(0, i - 1);
}
else if (i > 0)
{
str.erase(0, i);
}
i = str.size() - 1;
while (str != '.')
{
if (str != '0')
{
break;
}
i--;
}
if (i == str.find('.'))
{
str.erase(i);
}
else if (i < str.size() - 1)
{
str.erase(i + 1);
}
}
}
if (s == '-' && str != "0")
{
str.insert(0, 1, '-');
}
return str;
}
//(4)转换数组
const vector<int> lnum::strToVec(const string &s) const
{
vector<int> vint;
string str = s;
str == '-' ? str.erase(0, 1) : str;
hasDecPoint(str) > false ? str.erase(str.find('.'), 1) : str;
for (char c : str)
{
vint.push_back(c - 48);
}
return vint;
}
//(-4)转换字符串
const string lnum::vecToStr(const vector<int> &vint, int sgn, size_t dsz) const
{
string str;
for (int i : vint)
{
str.push_back(i + 48);
}
if (str != "0")
{
dsz == 0 ? str : str.insert(str.size() - dsz, 1, '.');
sgn == -1 ? str.insert(0, 1, '-') : str;
}
return str;
}
//(5)提取信息
const lnum::ndata lnum::getInfo(const string &s) const
{
ndata ndt = {0, "0", {0}, 1, 0};
if (isInvalidStr(s))
{
ndt.nstr = s;
ndt.sign = ndt.nstr != "0" ? (ndt.nstr == '-' ? -1 : 1) : 0;
ndt.dsize = hasDecPoint(ndt.nstr) || false ? ndt.nstr.size() - ndt.nstr.find('.') - 1 : 0;
ndt.nvec = strToVec(ndt.nstr);
ndt.isize = ndt.nvec.size() - ndt.dsize;
}
return ndt;
}
//(6)小数位对齐
lnum::align lnum::dAlign(const lnum &l) const
{
align agn;
vector<int> &f = agn.first, &s = agn.second;
f = data.nvec;
s = l.data.nvec;
const size_t &fds = data.dsize, &sds = l.data.dsize;
fds > sds ? s.insert(s.end(), fds - sds, 0) : f.insert(f.end(), sds - fds, 0);
return agn;
}
//(7)整体对齐
lnum::align lnum::wAlign(const lnum &l) const
{
align &&agn = this->dAlign(l);
vector<int> &f = agn.first, &s = agn.second;
const size_t &fws = data.isize, &sws = l.data.isize;
fws > sws ? s.insert(s.begin(), fws - sws, 0) : f.insert(f.begin(), sws - fws, 0);
return agn;
}
//(8)满十进一
void lnum::carry(vector<int> &v) const
{
v.insert(v.begin(), 1, 0);
const size_t s = v.size();
for (size_t i = s - 1; i != 0; i--)
{
int t = v;
v = t % 10;
v += t / 10;
}
if (v == 0)
{
v.erase(v.begin(), v.begin() + 1);
}
}
//(9)借一补十
void lnum::borrow(vector<int> &v) const
{
const size_t s = v.size();
for (size_t i = 1; i < s; i++)
{
v -= 1;
v += 10;
}
}
//(10)输出设置
const string lnum::setPrint() const
{
const size_t &tds = data.dsize;
string str = data.nstr;
if (pre == 0)
{
if (tds != 0)
{
str.erase(str.find('.'));
}
}
else if (tds > pre)
{
str.erase(str.size() - (tds - pre));
}
return clearInvalidZero(str);
}
//(11)lnum*n
const lnum lnum::operator*(const int &n) const
{
vector<int> t = data.nvec;
for (int &i : t)
{
i *= n;
}
carry(t);
lnum r = vecToStr(t, data.sign, data.dsize);
return r;
}
//==========================================================================
//(0)显示信息
void lnum::showinfo() const
{
std::cout << "正/负/零: " << data.sign << "\n"
<< "原始数字: " << data.nstr << "\n"
<< "数组元素: ";
for (int i : data.nvec)
{
std::cout << i << " ";
}
std::cout << std::endl;
std::cout << "整数位数: " << data.isize << "\n"
<< "小数位数: " << data.dsize << std::endl;
}
void lnum::setprecision(const size_t p)
{
pre = p;
}
//(1)>号
const bool lnum::operator>(const lnum &l) const
{
bool f = true;
const int &tsgn = data.sign, &lsgn = l.data.sign;
if (tsgn < lsgn)
{
f = false;
}
else if (tsgn == lsgn)
{
const align &agn = this->wAlign(l);
f = agn.first > agn.second;
if (tsgn == -1)
{
f = !f;
}
}
return f;
}
//(2)==
const bool lnum::operator==(const lnum &l) const
{
return (data.sign == l.data.sign) && (data.nvec == l.data.nvec);
}
//(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);
}
//(5.5)!=
const bool lnum::operator!=(const lnum &l) const
{
return !(*this == l);
}
//(6)+
const lnum lnum::operator+(const lnum &l) const
{
lnum r;
if (*this != (-l))
{
align agn = this->wAlign(l);
vector<int> &fst = agn.first,
&sec = agn.second,
&greater = fst >= sec ? fst : sec,
&less = sec <= fst ? sec : fst;
const int &tsgn = data.sign,
&lsgn = l.data.sign;
const size_t &sz = fst.size();
for (size_t i = 0; i < sz; i++)
{
greater += (lsgn * tsgn) * less;
}
int sgn = 1;
if (tsgn == lsgn)
{
sgn = tsgn;
}
else if (tsgn != lsgn)
{
sgn = ((greater == fst && tsgn < lsgn) || (less == fst && tsgn > lsgn)) || false ? -1 : sgn;
}
if (tsgn * lsgn == -1)
{
borrow(greater);
}
carry(greater);
size_t dsz = data.dsize >= l.data.dsize ? data.dsize : l.data.dsize;
//string str = vecToStr(greater, sgn, dsz);
r = vecToStr(greater, sgn, dsz);
}
return r;
}
//(7)-反转正负
const lnum lnum::operator-() const
{
lnum r = *this;
if (data.sign != 0)
{
r.data.sign = -data.sign;
r.data.nstr = vecToStr(data.nvec, -data.sign, data.dsize);
}
return r;
}
//(7.5)-
const lnum lnum::operator-(const lnum &l) const
{
return *this + (-l);
}
//(8)+=
const lnum &lnum::operator+=(const lnum &l)
{
return *this = *this + l;
}
//(9)++
const lnum &lnum::operator++(const int i)
{
return *this = *this + "1";
}
//(10)-=
const lnum &lnum::operator-=(const lnum &l)
{
return *this = *this + (-l);
}
//(11)--
const lnum &lnum::operator--(const int i)
{
return *this = *this + "-1";
}
//(12)lnum*lnum
const lnum lnum::operator*(const lnum &l) const
{
lnum r;
const int &tsgn = data.sign,
&lsgn = l.data.sign;
if (tsgn * lsgn == 0)
{
r = "0";
}
else
{
const vector<int> &tvec = data.nvec,
&lvec = l.data.nvec;
const size_t &tsz = data.dsize,
&lsz = l.data.dsize,
&tvsz = tvec.size(),
&lvsz = lvec.size(),
&shrtsz = tvsz <= lvsz ? tvsz : lvsz;
lnum loong = tvsz >= lvsz ? *this : l;
const vector<int> &shrtv = lvsz <= tvsz ? lvec : tvec;
vector<int> &lovec = loong.data.nvec,
&rvec = r.data.nvec;
for (size_t i = shrtsz - 1; i != -1; i--)
{
r += loong * shrtv;
if (i > 0)
{
lovec.push_back(0);
}
}
r = vecToStr(rvec, tsgn * lsgn, tsz + lsz);
}
return r;
}
//(F)<<
ostream &operator<<(ostream &os, const lnum &l)
{
os << l.setPrint();
return os;
}
//(F)>>
istream &operator>>(istream &is, lnum &l)
{
string str;
(std::cin >> str).get();
l = str;
return is;
}
===========================================
页:
[1]