因为不够 题解++2
2023-10-20 19:34:51
发布于:浙江
9阅读
0回复
0点赞
bool operator!=(const HPFloat &op1, const HPFloat &op2)
{
return !(op1 == op2);
}
bool operator<(const HPFloat &op1, const HPFloat &op2)
{//按符号、数量级、已用精度、各数位的顺序比较
if (op1 == hpfzero && op2 != hpfzero)//判断零
{
return !op2.Symbol;
}
if (op2 == hpfzero)//零的数量级比较特殊,不参与比较
{
return op1.Symbol;
}
if (op1.Symbol != op2.Symbol)//比较符号
{
return op1.Symbol;
}
if (op1.Digit != op2.Digit)//比较数量级
{
return (op1.Digit < op2.Digit);
}
long long sd1=op1.Sdig();
long long sd2=op2.Sdig();
long long t = (sd1 < sd2) ? sd1 : sd2;//提前准备数据,提升效率
for (long long i = 0; i <= t; i++)
{
if (op1.Num[sd1 - i] != op2.Num[sd2 - i])
{
return (op1.Num[sd1 - i] < op2.Num[sd2 - i]);//比较各数位
}
}
if (sd1 < sd2)//比较已用精度
{
return 1;
}
return 0;
}
bool operator<=(const HPFloat &op1, const HPFloat &op2)
{
return (op1 < op2 || op1 == op2);
}
bool operator>(const HPFloat &op1, const HPFloat &op2)
{//和<基本一致
if (op1 == hpfzero && op2 != hpfzero)
{
return op2.Symbol;
}
if (op2 == hpfzero )
{
return !op1.Symbol;
}
if (op1.Symbol != op2.Symbol)
{
return op2.Symbol;
}
if (op1.Digit != op2.Digit)
{
return (op1.Digit > op2.Digit);
}
long long sd1=op1.Sdig();
long long sd2=op2.Sdig();
long long t = (sd1 < sd2) ? sd1 : sd2;
for (long long i = 0; i <= t; i++)
{
if (op1.Num[sd1- i] != op2.Num[sd2 - i])
{
return (op1.Num[sd1 - i] > op2.Num[sd2 - i]);
}
}
if (sd1 > sd2)
{
return 1;
}
return 0;
}
bool operator>=(const HPFloat &op1, const HPFloat &op2)
{
return (op1 > op2 || op1 == op2);
}
HPFloat abs(const HPFloat &op)
{
HPFloat ans(op);
ans.Symbol = 0;
return ans;
}
HPFloat operator-(const HPFloat &op)
{
HPFloat ans(op);
ans.Symbol = !op.Symbol;
return ans;
}
HPFloat operator+=(HPFloat &op1, const HPFloat &op2)
{
if (op1.Symbol != op2.Symbol)//如果符号不同,传递给减法
{
HPFloat op3(op2);
if (op1.Symbol == 1)
{
op1.Symbol = 0;
op3 -= op1;
op1 = op3;
return op1;
}
else
{
op3.Symbol = 0;
op1 -= op3;
return op1;
}
}
{
if (op1 == hpfzero)//如果为零,直接返回
{
op1 = op2;
return op1;
}
}
long long sd=op2.Sdig();
long long mi=op2.Mindig();
for (long long i = 0; i <= sd; i++)//一个个传入到Dplus
{
op1.Dplus(op2.Num[i], mi + i);
}
HPFloat ans(op1);
return ans;
}
HPFloat operator+(const HPFloat &op1, const HPFloat &op2)
{
HPFloat op3(op1);
op3 += op2;
return op3;
}
HPFloat operator-=(HPFloat &op1, const HPFloat &op2)
{
HPFloat ans(op1);
ans = op1 - op2;
op1 = ans;
return ans;
}
HPFloat operator-(const HPFloat &op1, const HPFloat &op2)
{
if (op1.Symbol != op2.Symbol)//符号不同就传递给加法
{
if (op1.Symbol == 1)
{
HPFloat ans(op1);
ans.Symbol = 0;
ans = op1 + op2;
ans.Symbol = 1;
return ans;
}
else
{
HPFloat ans(op2);
ans.Symbol = 0;
ans += op1;
return ans;
}
}
if (op1 == hpfzero)
{
return -op2;
}
bool bg=(op1 >= op2);//确保传递时不发生小减大
HPFloat ans(bg ? op1 : op2);
HPFloat op((!bg)?op1 : op2);
ans.Symbol = (!bg);
ans.Simp();
op.Simp();
long long D = op.Mindig();
long long sd=op.Sdig();
for (long long i = 0; i <= sd; i++)//循环传递参数
{
ans.Dsub(op.Num[i], D + i);
}
return ans;
}
HPFloat operator*(const HPFloat &op1, const HPFloat &op2)
{
HPFloat ans;
ans.editlen(op1.Len());
long long sd1=op1.Sdig();
long long sd2=op2.Sdig();
long long mi1=op1.Mindig();
long long mi2=op2.Mindig();//提前提取需要重复使用的数据,提升效率
for (long long i = 0; i <= sd1; i++)
{
for (long long j = 0; j <= sd2; j++)
{
char t = op1.Num[i] * op2.Num[j];
if (t==0)
{
continue;//零不参与运算
}
HPFloat temp;
temp = t;
temp.Digit = mi1 + mi2 + i + j + (t >= 10);//计算两位相乘的数量级
ans += temp;//直接加进去
}
}
ans.Symbol = (op1.Symbol != op2.Symbol);//同号为正,异号为负
return ans;
}
HPFloat operator*=(HPFloat &op1, const HPFloat &op2)
{
op1 = op1 * op2;
HPFloat ans(op1);
return ans;
}
HPFloat operator/(const HPFloat &op1, const HPFloat &op2)
{
if (op2 == hpfzero)//定义除零错误
{
throw("ZeroDivide");
}
HPFloat ans;
ans.editlen(op1.Len()+1);
HPFloat num1(op1);
HPFloat num2(op2);
ans.Symbol = !(op1.Symbol == op2.Symbol);//确定符号
ans.Digit = op1.Digit - op2.Digit;//确定数量级
num1.Digit = 0;
num2.Digit = 0;
num1.Symbol = 0;
num2.Symbol = 0;//全部对齐,便于运算
ans.Digit -= (num1 < num2);//确定数量级
for (long long i = ans.Len() - 1; i >= 0; i--)//遍历ans输入商
{
while (num1 >= num2)//得出商
{
ans.Num[i]++;
num1 -= num2;
}
if (num1 <= hpfzero || num2 == hpfzero)//除尽时退出
{
break;
}
num2.Digit--;
}
ans.Mback(1);//退位,四舍五入掉最后一位
ans.Simp();
HPFloat temp(ans);
return temp;
}
HPFloat operator/=(HPFloat &op1, const HPFloat &op2)
{
op1 = op1 / op2;
HPFloat ans(op1);
return ans;
}
HPFloat &HPFloat::operator=(const HPFloat &op)
{
HPFloat num;//定义一个临时对象,避免遇到如a=a的语句时出现问题
num.editlen(op.Len());
long long sd=op.Sdig();
for (long long i = 0; i <=sd; i++)
{
num.Num[i] = op.Num[i];
}
num.Digit = op.Digit;
num.Symbol = op.Symbol;//需要手动负值,因为构造函数会调用=
empty();
long long i = (Len() - 1 > sd) ? sd : (Len() - 1);
for (long long j = 0; j <= i; j++)
{
Num[Len() - 1 - j] = num.Num[sd - j];
}
if (!((Len() - 1) >= sd))
{
if (num.Num[sd - (Len() - 1) - 1] >= 5)//精度不足时四舍五入
{
Lplus(1, 0);
}
}
Symbol = num.Symbol;
Digit = num.Digit;
Simp();
return *this;
}
HPFloat &HPFloat::operator=(const long long &op)
{
empty();
long long num = (op > 0) ? op : -op;//取正
short e = 0;
{
long long t = 1;
while (t <= num)
{
e++;//计算数位
t *= 10;
}
}
for (short i = 0; i <= e; i++)
{
Num[i] = num % 10;//逐个填入
num = (num - num % 10) / 10;
}
Digit = e - 1;
Symbol = (op < 0);
Simp();
return *this;
}
HPFloat &HPFloat::operator=(const int &op)//int较常用,不参与函数模板提升效率
{//longlong可兼容int,调用longlong
return *this = (long long)op;
}
HPFloat &HPFloat::operator=(const string &num)
{
HPFloat temp;
temp.editlen(num.size());
unsigned long eloc = 0;
while (num[eloc] != 'e' && num[eloc] != 'E' && eloc <= (num.size() - 1))//如果是科学计数法,先提出数量级
{
eloc++;
}
if (eloc < num.size() - 1)
{
temp.Digit = stoll(num.substr(eloc + 1, num.size() - 1));//写入数量级
}
string op = num.substr(0, eloc );
{
if (op[0] == '-')//提出负号
{
temp.Symbol = 1;
op.erase(0, 1);
}
{
long long l = 0;
while (op[l] == '0')//删掉多余的零
{
l++;
}
if (l != 0)
{
op.erase(0, l);
}
}
reverse(op.begin(), op.end());//倒序,和HPFloat的顺序相同
if (op[0] == '\0')//删掉结束符
{
op.erase(0, 1);
}
bool ifdot = 0;
long long dotloc = 0;
for (unsigned long long i = 0; i < op.size(); i++)
{
if (op[i] == '.')//记录小数点的位置
{
ifdot = 1;
dotloc = i;
continue;
}
if (op[i] < 48 || op[i] > 57)//遇到异常数据,抛出错误
{
throw("DataException");
return *this;
}
temp.Num[i - ifdot] = op[i] - 48;//录入数据
}
if (op[op.size() - 1] == '.')//如果小数点在末尾
{
op.erase(op.size() - 1, 1);
long long l = 0;
while (op[op.size() - 1 - l] == '0')
{
l++;
}
temp.Digit += -l - 1;//算出数量级
}
else
{
temp.Digit += op.size() - 1 - dotloc - ifdot;//算出数量级
}
temp.Simp();//化简返回
*this = temp;
return *this;
}
}
HPFloat &HPFloat::operator=(const double& num)
{
char tem[16]= {0};
sprintf(tem,"%f",num);//打印到字符串
string str=tem;
*this=str;//调用等号重载
return *this;
}
template < typename Ty>
HPFloat &HPFloat::operator=(const Ty &op)
{
return *this = (double)op;//转换到浮点
}
istream &operator>>(istream &in, HPFloat &op)
{
string temp;
in >> temp;//输入到字符,调用等号重载
op = temp;
return in;
}
ostream &operator<<(ostream &out, const HPFloat &op)
{//和expstr基本相同。因为string理论上有上限,所以这里不调用expstr
if (!op.outtype)
{
if (op.Symbol==1)
{
out<<'-';
}
if (op.Digit < 0)
{
out << "0.";
for (long long i = -1; i > op.Digit; i--)
{
out << '0';
}
}
for (long long i = op.Sdig(); i >= 0; i--)
{
out << (int)op.Num[i];
if (op.Sdig() - i == op.Digit && i != 0)
{
out << '.';
}
}
for (long long i = op.Mindig(); i > 0; i--)
{
out << '0';
}
}
else
{
if (op.Symbol==1)
{
out<<'-';
}
out << (int)op.Num[op.Sdig()] << '.';
for (long long i = op.Sdig() - 1; i >= 0; i--)
{
o
这里空空如也
有帮助,赞一个