高精度加减乘除
为什么需要高精度?
int 占4字节,由于一字节占8位,所以int能表示的范围为-231~231-1(首位表示的符号)
它的长度是10.而long long是8字节,能表示的范围是-263~263-1,它的长度是19位.由于最大的位数表示仅仅才19位,所以我们需要一个有效的方法去计算更高位的数字运算.
在所有的高位数中,都用字符串然后逆向存入数组中.
cin >> str;
for (int i = 0; i < str.size(); ++ i)
arr[i] = str[str.size() - i - 1] - '0';
高精度加法
void add(int a[], int b[], string s1, string s2)
{
int len = max(s1.size(), s2.size());
for (int i = 0, i < len; ++i)
c[i] = a[i] + b[i];
for (int i = 0, i < len; ++i)
{
if (c[i] >= 10)
{
c[i + 1] += c[i] / 10;
c[i] %= 10;
}
}
if (c[len]) cout << c[len];
for (int i = len - 1, i >= 0; --i)
cout << c[i];
}
高精度减法
void sub(int a[], int b[], string s1, string s2)
{
if (s1.size() < s2.size() || s1.size() == s2.size() && s1 < s2)
{
cout << '-';
swap(s1, s2);
}
for (int i = 0, i < s1.size(); ++i)
a[s1.size() - 1 - i] = s1[i] - '0';
for (int i = 0, i < s2.size(); ++i)
b[s2.size() - 1 - i] = s2[i] - '0';
int len = s1.size();
for (int i = 0, i < len; ++i)
c[i] = a[i] - b[i];
for (int i = 0, i < len; ++i)
{
if (c[i] < 0)
{
c[i + 1] -= 1;
c[i] += 10;
}
}
int k = len - 1;
while (!c[k]) -- k;
if (k == -1) cout << '0';
else
for (int i = k, i >= 0; --i)
cout << c[i];
}
高精度乘法
高精度乘以低精度
//将每位数字乘以低精度,然后再进行进位处理,最后逆序输出
void multi(int arr[], str)
{
int len = str.size();
for(int i = 0; i <= len; ++i)
arr[i] * lowData;
for(int i = 0; i <= len; ++i)
if (arr[i] >= 10)
{
arr[i + 1] = arr[i + 1] + a[i] / 10;
arr[i] = arr[i] % 10;
}
//考虑是否进位,需要依情况而定
if (arr[len + 1]) cout << arr[len + 1];
for (int i = len; i >= 0; -- len) cout << arr[i];
}
高精度乘以高精度
void multi_plus(int a[], int b[], string s1, string s2)
{
int lena = s1.size();
int lenb = s2.size();
for (int i = 0; i < lenb; ++i)
for (int j = 0; j < lena; ++j)
{
c[j + i] += a[j] * b[i];
if (c[j + i] >= 10)//注意错位相加
{
c[j + i + 1] += c[j + i] / 10;
c[j + i] %= 10;
}
}
int k = lena + lenb + 1;
while (k != -1 && !c[k]) --k;//找到第一个不为0的数,去除前导0
if (k == -1) cout << '0';
else
for (int i = len; i >= 0; -- len) cout << arr[i];
}
高精度整数除法
a除以b保留前n为小数
void div()
{
cin >> a >> b >> n;
if (!n)
{
cout << a / b;
return;
}
res.append(to_string(a / b) + '.');
int t = (a % b) * 10;
int k = 0;//小数点位数
while (k < n - 1)
{
res.append(to_string(t * 10 / b));
t = (t * 10) % b;
++k;
}
cout << res;
}