由于是分数,所以肯定为有限小数或者无限非循环小数。所以,找出循环节之前的数才是关键。
然后记录一下循环节第一个数,模拟往后除,直到有相同数为止。
先贴出原理:
一个最简分数化为小数有三种情况:
(1)如果分母只含有质因数2和5,那么这个分数一定能化成有限小数,并且小数部分的位数等于分母中质因数2与5中个数较多的那个数的个数;
(2)如果分母中只含有2与5以外的质因数,那么这个分数一定能化成纯循环小数;
(3)如果分母中既含有质因数2或5,又含有2与5以外的质因数,那么这个分数一定能化成混循环小数,
并且不循环部分的位数等于分母中质因数2与5中个数较多的那个数的个数。
给个例题:
写一个程序,输入一个形如N/D的分数(N是分子,是分母),输出它的小数形式。如果小数有循环节的话,把循环节放在一对圆括号中。
例如:
1/3 = .33333333 写成0.(3)
41/333 = 0.123123123... 写成0.(123)
用xxx.0 成表示整数典型的转化例子:
1/3 = 0.(3)
22/5 = 4.4
1/7 = 0.(142857)
2/2 = 1.0
3/8 = 0.375
45/56 = 0.803(571428)
源代码:
#include <cstdio>
int main()
{
freopen("fracdec.in","r",stdin);
freopen("fracdec.out","w",stdout);
int N,D;
while(scanf("%d %d",&N,&D)!=EOF)
{
printf("%d.",N/D);
int yu = N%D;
if(yu == 0)printf("0\n");
int sum2=0,sum5=0;
int d1 = D;
while(d1%2 == 0){++sum2;d1/=2;}//找因子2的个数
d1 = D;
while(d1%5 == 0){++sum5;d1/=5;}//找因子5的个数
int num = sum2>sum5?sum2:sum5;//判断非循环节的个数,按照上述规则
for(int i = 1;i <= num;i++)
{
printf("%d",yu*10/D);
yu = yu * 10 %D;
}
if(yu != 0)//若不为0,则后面有循环节
{
int yu1 = yu;//yu记录当前余数
printf("(");
do
{
printf("%d",yu1*10/D);
yu1 = yu1*10%D;
}while(yu1 != yu);//余数相同是则表示经过了一个循环
printf(")\n");
}
}
return 0;
}