|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
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> |
|