#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<typeinfo>
#include<sstream>
#include<fstream>
#include<algorithm>
#include<map>
using namespace std;
const int MAX = 1000;
struct superNum{
int s[MAX],len=0;
char sign = '+';
//多态->重载string
superNum operator=(const string n){
len = n.length(); //永久存在structure里
if(n[0] == '-'){
sign = '-';
len--; //去掉符号位
for(int i=0;i<len;i++){ //跳过符号位
s[i] = n[len-i] - '0'; //倒序存储
}
}else{
sign = '+';
for(int i=0;i<len;i++){ //跳过符号位
s[i] = n[len-i-1] - '0'; //倒序存储
}
}
//this是指针 -> *this取值!
return *this; //返回本structure地址 ->同类替换????
}
//多态->重载int
superNum operator=(const int n){
stringstream ss;
ss << n;
string m = ss.str();
*this = m; //化归到已有
return *this;
}
//将构造func 化归到已有
//局部变量要初始化 !!! ->否则后果自负!
superNum(){memset(s,0,sizeof(s));} //构造函数 -> 初始化
superNum(const int n){memset(s,0,sizeof(s));*this = n;}
superNum(const string n){memset(s,0,sizeof(s));*this = n;}
//重载+
superNum operator+(superNum &a){
//同号用加法,异号用减法
if(sign =='+' && a.sign == '-'){a.sign='+';return *this - a;} //正数+负数
if(sign =='-' && a.sign == '+'){sign='+';return a - *this;} //负数+正数
//同号
superNum c; //return的结果
if(sign == '-') c.sign = '-'; //是同负
c.len = max(len,a.len) + 1; //①确定位数
int x =0;
for(int i=0;i<c.len;i++){
c.s[i] = this->s[i] + a.s[i] + x; //②单位运算
x = c.s[i] / 10; // ③进位运算
c.s[i] %=10;
}
c.len = c.s[c.len-1] == 0 ? c.len-1 : c.len; //④退位运算
return c; //c 与 *this形式相似
}
//重载+=
superNum operator+=(superNum &a){
/*superNum d;
d = *this+a;
return d;*/
//why??
*this = *this + a; //化归到已有
return *this;
}
//重载*
superNum operator*(superNum &a){
superNum c;
c.len = len + a.len; //len = this->len
if( (a.sign == '-' && sign !='-') || (a.sign != '-' && sign =='-') ) c.sign = '-'; //异号相乘为负
int x =0;
for(int i=0;i<len;i++){
for(int j=0;j<a.len;j++){ //乘法竖式 ->二维计算
c.s[i+j] += s[i]*a.s[j];
c.s[i+j+1] += c.s[i+j] / 10; //两个+=
c.s[i+j] %=10;
}
}
c.len = c.s[c.len-1] == 0 ? c.len-1 : c.len;
return c;
}
//重载*=
superNum operator*=(superNum &a){
*this = *this * a;
return *this;
}
//重载比较运算符 -> <和>的相对性 ->换位置
bool operator<(const superNum &a)const{
if(sign == '-' && a.sign !='-')return true; //①比较符号
if(sign != '-' && a.sign == '-')return false;
//s[0]存最高位
if(sign == '+'){ //为正,数大则大
if(len < a.len) return true; //②比较位数
if(len > a.len) return false; //取补集,和为R
for(int i=len-1;i>=0;i--){
if(s[i] < a.s[i]) return true;
if(s[i] > a.s[i]) return false;
}
}else{
if(len < a.len) return false; //②比较位数
if(len > a.len) return true; //取补集,和为R //为负,数大反小
for(int i=len-1;i>=0;i--){
if(s[i] < a.s[i]) return false;
if(s[i] > a.s[i]) return true;
}
}
return false; //等于的情况
}
bool operator>(const superNum &a){ //operator前面写返回值类型
return a < *this; //大小换位相对性
}
//在<和>的基础上,一切取补集
bool operator<=(const superNum &a){
return !(*this > a);
}
bool operator>=(const superNum &a){
return !(*this < a);
}
bool operator==(const superNum &a){
return !(*this < a) && !(*this > a);
}
//重载- 需要比较大小 -> 先重载<和>
superNum operator-(superNum &a){
//同号相减用减法,异号相减用加法
if(sign =='+' && a.sign == '-'){a.sign='+';return *this + a;} //正数-负数
if(sign =='-' && a.sign == '+'){a.sign='-';return *this + a;} //负数-正数
//同号
superNum d;
if(sign == '+'){ //正数-正数
d = sub(*this,a);
}else{ //负数-负数
d = sub(a,*this); //结构体内部定义func好返回structure
}
return d;
}
//将同位相减,解耦出来
superNum sub(superNum &a,superNum &b){
superNum c;
a.sign = b.sign = '+';
if(a >=b){ //确保被减数更大 //要纯粹比较大小要取绝对值 -> 重载的比较运算符会看符号了!
c.len = a.len;
for(int i=0;i<c.len;i++){ //大数主导位数
if(a.s[i]<b.s[i]){ //借位
c.s[i+1]--;
c.s[i] += a.s[i]+10-b.s[i];
}else{
c.s[i] += a.s[i]-b.s[i];
}
}
//减法的位数不确定大 -> 额外循环1次
int x=0;
while(c.s[c.len-1-x] ==0 && c.len >1)c.len--;x++;
}else{
c.len = b.len;
for(int i=0;i<c.len;i++){ //大数主导位数
if(b.s[i]<a.s[i]){ //借位
c.s[i+1]--;
c.s[i] += b.s[i]+10-a.s[i]; //+=存量
}else{
c.s[i] += b.s[i]-a.s[i];
}
}
int x=0;
while(c.s[c.len-1-x] ==0 && c.len >1)c.len--;x++;
c.sign ='-';
//将修改符号置后,以免干扰比较大小!!
}
return c;
}
}; //结构体末尾加;
//在structure外,重载全局运算符 << 和 >>
istream &operator>>(istream &in,superNum &a){ //ostream为class,格式与superNum一样
string s;
in >> s; //i代表cin传入
a = s;
if(s[0] == '-'){a.sign='-';}//赋值时,都要修改符号
else{a.sign='+';}
return in; //保证cin继续运行
}
ostream &operator<<(ostream &out,const superNum &a){ //ostream为class,格式与superNum一样
if(a.sign == '-') cout << "-"; //先输出符号
for(int i=a.len-1;i>=0;i--){ //out -> cout; len -> a
// 倒序输出
cout << a.s[i];
}
return out; //保证cout继续运行
}
int main()
{
superNum k=5,p=-345,q=-4000;
//k += p;
//p *= q;
//k *= q;
cout << p-q;
//if(p<q)cout << "a";
return 0;
}
//cout << "输入:";
structure高精度运算(除法以外,皆有!!)包括负数,永久存储
最新推荐文章于 2024-03-11 23:06:56 发布