题目:
请写出一个程序,接受一个以N/D(0<=N<=65535,0<=D<=65535)的形式输入的分数,其中N为分子,D为分母,输出它的小数形式(运算结果小数点后最多保留100位)。假如它的小数形式存在循环节,要将其用括号括起来。例如:1/3=.33333...表示为.(3),又如41/333=.123123123...表示为.(123)。
一些转化的例子:
1/3=0.(3)
22/5=4.4
1/7=0.(142857)
3/8=0.375
11/59= 0.(1864406779661016949152542372881355932203389830508474576271)
45/47=0.(9574468085106382978723404255319148936170212765)
17/79= 0.(2151898734177)
16/33= 0 .(48)
思路:完全模拟除法运算,可以手算一下来理解,直接用float,double精度是不够的。
#include <iostream>
#include <cstdio>
using namespace std;
int main(){
int res[150], mod[150];
int n, m;
cin >> n >> m;
res[0] = n / m; //res[0]存小数的整数部分,res[1~]存放小数部分
mod[0] = n % m; //mod 存放除不开的余数部分
int cnt = 1;
int i = 0, x = 0, j = 0;
while(cnt <= 100 && mod[cnt - 1] != 0){
res[cnt] = (mod[cnt - 1] * 10) / m; //完全模拟除法,可以手动除法来理解,10 / 7 -> 3 / 7 => 3 * 10 / 7 ->
mod[cnt] = (mod[cnt - 1] * 10) % m;
if(mod[cnt] == 0)
break;
else{
for(i = 1; i < cnt; i++){ //找循环节
if(mod[i] == mod[cnt]){ //余数相同则后面的运算就相同,就是循环节
break; //循环节从i开始到cnt - 1
}
}
if(i < cnt){
x = i; //记录循环节开始的位置
break;
}
}
cnt++;
}
if(x == 0){ //无循环节
cout << res[0] << ".";
for(i = 1; i <= cnt; i++)
cout << res[i];
}
else{ //循环小数
cout << res[0] << ".";
for(i = 1; i < x; i++)
cout << res[i];
cout << "(";
for(i = x; i < cnt; i++)
cout << res[i];
cout << ")";
}
return 0;
}