昨天做了一道竞赛的题目,却被难住了……
题目如下:
给定一个分数N/D(N,D均为整数),试编程求出N/D的小数形式,如果这个小数为无限循环小数,则把循环部分括起来,接着循环部分不写。比如:
22/5=4.4;
1/7=0.(142857)
2/2=1.0
45/56=0.803(571428)
初看这个题目,不知从何入手,其实分数就是全体有理数,而有理数又分为整数,有限小数和无限循环小数,无理数则是无限不循环小数。所以任何分数化为小数只有两种结果,一是有限小数,一是循环小数,而循环小数又分为纯循环小数(如1/7=0.[142857])和混循环小数(如45/56=0.803[571428])两类。那么,什么样的分数能化成有限小数?什么样的分数能化成纯循环小数、混循环小数呢?
针对最简分数:
①如果分母的质因数只含有2和5,则这个分数就能化成有限小数,并且小数部分的位数等于分母中质因数2与5中个数较多的那个数的个数;
②如果分母的质因数不含有2和5,则这个分数就能化成纯循环小数。
③如果分母的质因数既含有2或5,又含有2与5以外的质因数,那么这个分数一定能化成混循环小数,并且不循环部分的位数等于分母中质因数2与5中个数较多的那个数的个数。
源代码如下:
#include<iostream> using namespace std; int CommonFactor(int m,int n) { int r=m%n; while(r!=0) { m=n; n=r; r=m%n; } return n; } void FractionToDecimal(int n,int d) { int GCD=CommonFactor(d,n); if(GCD>1)//除以最大公约数 { n/=GCD; d/=GCD; } cout<<n/d<<"."; if(n>=d) n%=d; if(n==0) cout<<n<<endl; else { int counter2=0,counter5=0; int s=d; while(s%2==0) { counter2++; s/=2; } while(s%5==0) { counter5++; s/=5; } if(s==1)//只含2或5,有限小数 { while(n!=0) { n*=10; cout<<n/d; n%=d; } cout<<endl; } else { if(counter2>0||counter5>0)//纯循环小数 { int SIZE=counter2>counter5? counter2:counter5; for(int i=0;i<SIZE;i++) { n*=10; cout<<n/d; n%=d; } } cout<<"("; int m=n; while(m!=0) { m*=10; cout<<m/d; m%=d; if(n==m) break; } cout<<")"<<endl; } } } void main() { int N,D; cout<<"Please input the numerator and denominator:/n"; cin>>N>>D; FractionToDecimal(N,D); }
测试时,无意中输入了一个很有意思的分数,得到的结果真是令我吃一惊》》》》
如果人去算这个小数不算死个人啊………………!!!!!!!!!!!!!!!!!