求小数的循环节

求小数的循环节:

如X=4,Y=7; 输出:X/Y=0.(5714285714)


解法:很简单,利用不断计算X=X%Y的值是否为0,如果为0,说明是一个有限小数,如果不为0,判断这个值之前是否出现过,如果出现过说明我们已经找到了这个小数的循环节

#include<iostream>
using namespace std;
#define MAXLENGTH 100
int ANS[MAXLENGTH];//存储答案
int r[MAXLENGTH];//存储余数
int main()
{
	int j, LEN=0;
	int x=6,y=6;
	while(true)
	{
		ANS[LEN]=x/y;//表示整数部分(ANS[0])
		x=x%y;
		for(j=LEN;j>0;j--)//从余数表里往回找,直到第一个重复,余数表从下标一开始放
			if(x==r[j])
				break;//找到了第一个重复点退出
		if(x==0||j>0)//j表示第一个重复点,或者已经除尽,退出循环
			break;
		else
			r[++LEN]=x;
		x=x*10;
	}
	//打印结果
	cout<<ANS[0]<<".";
	for(int i=1;i<=LEN;i++)
	{
		if(i==j)
			cout<<"(";
		cout<<ANS[i];
	}
	if(x!=0) cout<<")";
	cout<<endl;
	system("pause");
	return 0;
}


上面的做法,每当精度提高一次时就要,遍历次R,判断这个余数是否出现过,效率太低!!我们知道每次计算余数的范围在0-到Y-1(Y是除数),因此我们可以保存一个大小为Y的数组R,初始为-1,每当产生一个大小为R的余数,我们可以查询R[r]是否出现过,如果出现过了,说明我们找到的了小数的循环节,如果没有,令R[r]=true


#include<iostream>
using namespace std;
int ANS[1000];//存放运算结果,其中ANS【0】表示整数部分
int R[1000];//存放运算结果,其中ANS【0】表示整数部分
void Div(int x,int y)
{
	if(y==0)
		return;
	for(int i=0;i<y;i++)
		R[i]=-1;
	int len=0;//结果的长度
	//计算整数部分的余数
	ANS[len]=x/y;
	x=x%y;
	while(x!=0&&R[x]<0)
	{
		R[x]=len;//用来表示这是第几次除法产生的余数
		x*=10;
		ANS[++len]=x/y;
		x=x%y;	
	}
	//打印小数
	if(x==0)//是有限小数
	{
		cout<<ANS[0]<<".";
		for(int i=1;i<=len;i++)
			cout<<ANS[i];
	}else
	{
		cout<<ANS[0]<<".";
		for(int i=1;i<=len;i++)//注意这里最后一位已经开始循环了
		{
			if(i==R[x]+1)
				cout<<"(";
			cout<<ANS[i];
		}
		cout<<")";
	}
}
int main(int argc,char* argv[])
{
	Div(4,127);
	system("pause");
	return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值