c++高精度实现

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include <bits/stdc++.h>
using namespace std;
struct fantastic {
int len, s[9999];

fantastic() {
memset(s, 0, sizeof(s));
len = 1;
}
fantastic& operator=(const char* num) {
len = strlen(num);
for (int i = 0; i < len; ++i)
s[i] = num[len - i - 1] - '0';
return *this;
}

fantastic& operator=(const int num) {
char a[9999];
sprintf(a, "%d", num);
*this = a;
return *this;
}

fantastic(const int num) { *this = num; }
fantastic(const char* num) { *this = num; }
bool operator<(const fantastic& a) const {
if (len != a.len) return len < a.len;
for (int i = len - 1; i >= 0; --i)
if (s[i] != a.s[i]) return s[i] < a.s[i];
return false;
}

bool operator>=(const fantastic& a) const { return !(*this < a); }
bool operator==(const fantastic& a) const {
if (len != a.len) return false;
for (int i = 0; i < len; ++i)
if (s[i] != a.s[i]) return false;
return true;
}
bool operator!=(const fantastic& a) const { return !(*this == a); }

fantastic operator+(const fantastic& a) {
fantastic c;
c.len = max(len, a.len) + 1;
for (int i = 0, x = 0; i < c.len; ++i) {
c.s[i] = s[i] + a.s[i] + x;
x = c.s[i] / 10;
c.s[i] %= 10;
}
if (c.s[c.len - 1] == 0) --c.len;
return c;
}

fantastic operator-(const fantastic& a) const{
if (*this < a) throw invalid_argument("Negative result");
fantastic c;
c.len = len;
int borrow = 0;
for (int i = 0; i < c.len; ++i) {
int sub = s[i] - borrow;
if (i < a.len) sub -= a.s[i];
if (sub < 0) { sub += 10; borrow = 1; }
else borrow = 0;
c.s[i] = sub;
}
while (c.len > 1 && c.s[c.len-1] == 0) --c.len;
return c;
}

fantastic operator*(const fantastic& x) const{
fantastic c;
c.len = len + x.len;
for (int i = 0; i < len; ++i)
for (int j = 0; j < x.len; ++j) {
c.s[i+j] += s[i] * x.s[j];
c.s[i+j+1] += c.s[i+j] / 10;
c.s[i+j] %= 10;
}
while (c.len > 1 && c.s[c.len-1] == 0) --c.len;
return c;
}

fantastic operator/(const fantastic& divisor) const {
if (divisor == fantastic(0)) throw invalid_argument("Division by zero");
fantastic quotient, remainder = *this;
quotient.len = max(1, len - divisor.len + 1);

for (int i = quotient.len-1; i >= 0; --i) {
fantastic temp = divisor;
temp.shift_left(i);

int count = 0;
while (remainder >= temp) {
remainder = remainder - temp;
count++;
}
quotient.s[i] = count;
}
while (quotient.len > 1 && quotient.s[quotient.len-1] == 0)
--quotient.len;
return quotient;
}

fantastic operator%(const fantastic& divisor) const {
if (divisor == fantastic(0)) throw invalid_argument("Modulus by zero");
fantastic quotient = *this / divisor;
fantastic product = quotient * divisor;
return *this - product;
}
void shift_left(int n) {
if (len == 1 && s[0] == 0) return;
for (int i = len-1; i >= 0; --i) s[i+n] = s[i];
for (int i = 0; i < n; ++i) s[i] = 0;
len += n;
}
};
ostream& operator<<(ostream& out, const fantastic& x) {
for (int i = x.len-1; i >= 0; --i) out << x.s[i];
return out;
}

istream& operator>>(istream& in, fantastic& x) {
char num[9999];
in >> num;
x = num;
return in;
}

解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#include <bits/stdc++.h> // 包含大部分标准库,但可能影响编译速度和可移植性
using namespace std; // 可能引发命名冲突,但简化代码


struct fantastic {
int len, s[9999]; // len为数字位数,s逆序存储各位数字(如"123"存为s[0]=3,s[1]=2,s[2]=1)


fantastic() { // 默认构造函数,初始化数字为0
memset(s, 0, sizeof(s));
len = 1;
}


// 从字符串赋值,逆序存储
fantastic& operator=(const char* num) {
len = strlen(num);
for (int i = 0; i < len; ++i)
s[i] = num[len - i - 1] - '0'; // 反转字符顺序存入数组
return *this;
}


// 从整数赋值,转换为字符串后处理
fantastic& operator=(const int num) {
char a[9999];
sprintf(a, "%d", num);
*this = a; // 复用字符串赋值逻辑
return *this;
}


fantastic(const int num) { *this = num; } // 整数构造函数
fantastic(const char* num) { *this = num; } // 字符串构造函数


// 比较运算符:按位数和逐位值比较
bool operator<(const fantastic& a) const {
if (len != a.len) return len < a.len;
for (int i = len-1; i >= 0; --i) // 从高位开始比较
if (s[i] != a.s[i]) return s[i] < a.s[i];
return false;
}


bool operator>=(const fantastic& a) const { return !(*this < a); }

// 相等判断需位数和各位值完全相同
bool operator==(const fantastic& a) const {
if (len != a.len) return false;
for (int i = 0; i < len; ++i)
if (s[i] != a.s[i]) return false;
return true;
}

bool operator!=(const fantastic& a) const { return !(*this == a); }


// 加法:逐位相加处理进位
fantastic operator+(const fantastic& a) {
fantastic c;
c.len = max(len, a.len) + 1; // 结果位数可能比最大位数多1
for (int i = 0, x = 0; i < c.len; ++i) {
c.s[i] = s[i] + a.s[i] + x;
x = c.s[i] / 10; // 计算进位
c.s[i] %= 10;
}
if (c.s[c.len-1] == 0) --c.len; // 去除前导零
return c;
}


// 减法:确保被减数不小于减数,处理借位
fantastic operator-(const fantastic& a) const {
if (*this < a) throw invalid_argument("Negative result");
fantastic c;
c.len = len;
int borrow = 0;
for (int i = 0; i < c.len; ++i) {
int sub = s[i] - borrow;
if (i < a.len) sub -= a.s[i];
borrow = sub < 0 ? 1 : 0; // 计算借位
c.s[i] = (sub + 10) % 10; // 处理负数结果
}
while (c.len > 1 && c.s[c.len-1] == 0) --c.len; // 去除前导零
return c;
}


// 乘法:竖式乘法,处理进位
fantastic operator*(const fantastic& x) const {
fantastic c;
c.len = len + x.len; // 最大可能位数
for (int i = 0; i < len; ++i)
for (int j = 0; j < x.len; ++j) {
c.s[i+j] += s[i] * x.s[j]; // 累加乘积
c.s[i+j+1] += c.s[i+j] / 10; // 处理进位
c.s[i+j] %= 10;
}
while (c.len > 1 && c.s[c.len-1] == 0) --c.len; // 去除前导零
return c;
}


// 除法:长除法,通过减法试商
fantastic operator/(const fantastic& divisor) const {
if (divisor == fantastic(0)) throw invalid_argument("Division by zero");
fantastic quotient, remainder = *this;
quotient.len = max(1, len - divisor.len + 1); // 商位数估计
for (int i = quotient.len-1; i >= 0; --i) {
fantastic temp = divisor;
temp.shift_left(i); // 除数左移i位(相当于乘10^i)
int count = 0;
while (remainder >= temp) { // 试减统计当前位商值
remainder = remainder - temp;
count++;
}
quotient.s[i] = count;
}
while (quotient.len > 1 && quotient.s[quotient.len-1] == 0)
--quotient.len; // 去除前导零
return quotient;
}


// 取模:利用除法结果计算余数
fantastic operator%(const fantastic& divisor) const {
fantastic quotient = *this / divisor;
return *this - quotient * divisor; // 余数=被除数-商×除数
}


// 左移n位(数值乘10^n),用于除法运算
void shift_left(int n) {
if (len == 1 && s[0] == 0) return; // 0左移不变
for (int i = len-1; i >= 0; --i)
s[i+n] = s[i]; // 高位右移n位
for (int i = 0; i < n; ++i)
s[i] = 0; // 低位补零
len += n; // 更新长度
}
};


// 输出运算符:逆序打印数组
ostream& operator<<(ostream& out, const fantastic& x) {
for (int i = x.len-1; i >= 0; --i) out << x.s[i];
return out;
}


// 输入运算符:读取字符串构造对象
istream& operator>>(istream& in, fantastic& x) {
char num[9999];
in >> num;
x = num; // 调用字符串赋值运算符
return in;
}


/* 潜在问题提示:
1. 数组固定大小9999可能溢出,超长输入导致越界。
2. 乘法和移位可能超出数组范围,需确保操作数位数足够小。
3. 除法效率较低,大数运算时性能不佳。
4. 未处理负数,仅限于非负整数运算。
*/

c++高精度实现
https://chenxi-tijie.pages.dev/2025/05/c-高精度实现/
作者
chenxi
发布于
2025年5月27日
许可协议