给定整数 m m m , n n n , k k k ,求 m / n m/n m/n 后保留 k k k 位小数,返回字符串形式。
C/C++ 内置的 float
类型一般表示精度受到整数部分大小的影响,因为 float
遵循 IEEE754 浮点数表示法,小数部分需要先转换到整数部分的指数和尾数表示再和整数进行相加,这个转换过程会导致小数部分的丢失,超过
1
0
6
10^6
106 的浮点数基本上无法表示小数了。
所以高精度除法就是利用字符串表示任意位数的小数部分。
#include <iostream>
#include <string>
using namespace std;
int abs(int x) {
if (x < 0) return -x;
return x;
}
int main(int argc, char** argv)
{
if (argc ^ 4)
{
cerr << "usage: " << argv[0] << " <dividend> <divisor> <precision>" << endl;
exit(-1);
}
int a = atoi(argv[1]);
int b = atoi(argv[2]);
int c = atoi(argv[3]);
if (c < 0)
{
cerr << "invalid precision" << endl;
exit(-1);
}
cout << a << " / " << b << " = ";
char s = a * b > 0 ? '+' : '-';
a = abs(a), b = abs(b);
string ans = "";
ans += s;
ans += std::to_string(a / b); // integer part
ans += ".";
a -= a / b * b;
for (int i = 0; i < c; ++i)
{
a *= 10;
ans += std::to_string(a / b);
a -= a / b * b;
}
cout << ans << endl;
return 0;
}
测试:
输入:
10 -3 10
输出:
-3.3333333333
输入:
1 -3 10
输出:
1 / -3 = -0.3333333333
输入:
-7 +9 10
输出:
-0.7777777777
- 使用两数异或,得到除法结果的符号正负,对于符号位异或来说,同为零异为一
- 模仿竖式除法,先获得整数部分,余数部分加零在对除数进行除法探测获得商
- 根据给定的精度循环进行竖式除法,对于可以整除的算式来说,高精度除法就是后面带非常多的零