使用数组精确计算M/N(0<M<n<=100)的值。如果M/N是无限循环小数,则计算输出它的第一循环节,同时要求输出循环节的起止位置(小数位的序号)。
1.问题分析与算法设计
由于计算机内字长有限,常规的浮点运算都有精度限制,为了得到高精度的计算结果,就必须自行设计实现算法。
为了实现高精度计算,可将商存放在一维数组中,数组的每个元素存放一位十进制数,即商的第一位存放在第一个元素中,商的第二位存放在第二个元素中……,依次类推。这样就可以使用数组来表示一个高精度的计算结果。
进行除法运算时可以模拟认得手工操作,即每次求出商的一位后,将余数乘以10,再计算商的下一位,重复以上过程。当某次计算后的余数为0时,表示M/N为有限不循环小数;当某次计算后的余数与前面的某个余数相同时,则M/N为无限循环小数,从该余数第一次出现之后所求得的各位就是小数的循环节。
程序具体实现时,采用了数组和其它一些技巧来保存除法运算所得到的余数和商的各位数。
2.程序与程序注释
#include<stdio.h>
int remainder[101]; //存放除法的余数
int quotient[101]; //依次存放商的每一位
void main()
{
int m,n,i,j;
printf("Please input a fraction (m/n)(0<m<n<=100):");
scanf("%d/%d",&m,&n); //输入被除数和除数
printf("%d/%d it's accuracy value is:0.",m,n);
for(i=1;i<=100;i++) //i商的位数
{
remainder[m] = i; //m除的余数 ramainder[m]该余数对应的商的位数
m *= 10; //余数扩大十倍
quotient[i] = m/n; //商
m = (m%n); //求余数
if(m==0) //余数为0则表示是有限小数
{
for(j=1;j<=i;j++)
{
printf("%d",quotient[j]); //输出商
}
break; //退出循环
}
if(remainder[m]!=0) //若该余数对应的位在前面已经出现过
{
for(j=1;j<=i;j++)
{
printf("%d",quotient[j]);//则输出循环小数
}
printf("\n\tand it is a infinite cyclic fraction from %d\n",remainder[m]);
printf("\tdigit to %d digit after decimal point.\n",i);//输出循环节的位置
break;
}
}
}
3.运行结果
输入:1/40 输出0.025
输入:25/95 输出 0.263157894736842105 小数点后1到18为循环节。