如何解决,详见程序。
//#include"stdafx.h"//VS默认使用
#include
#include
#include
#pragmawarning(disable:4996)
//为了最大限度支持(目前)小数,整数定义成:__int64
//支持32位:以下分别为int(__int32)1E8
#defineZHENGSHU__int64
#defineXIAOSHUDIANZUOYI1E15//double最多只能确精确到15位有效数字
#defineXIUZHENG1E-16//用于修正浮点数计算误差
int_tmain(intargc,_TCHAR*argv[])
{
//怎样用c语言写一个将小数转化成最简分数的算法
//开始
doublexs=0.000625;//为了简便,直接指定。也可以让用户输入
//scanf("%lf",&xs);
ZHENGSHUfz,fm,zs,k,fh;
//数学算法是:如0.123456=123456/1000000,然后约分
//实现第一步转换
if(xs<0)
{
fh=-1;
xs=-xs;
}
else
{
fh=1;
}
zs=(ZHENGSHU)xs;//支持假分数
//计算整数部分的有效数位数
k=1;
while(zs/k>0)
k*=10;
xs-=(double)zs;
fm=XIAOSHUDIANZUOYI/k;//分母
xs=(double)((ZHENGSHU)((xs+XIUZHENG*k)*fm))/fm;//修正浮点数计算误差
xs+=XIUZHENG;//修正浮点数计算误差
fz=(ZHENGSHU)(xs*fm);//分子
for(;;)//这样循环,是因为C/C++中,for循环效率最高
{//约去多乘的10的倍数
if((fz%10==0)&&(fm%10==0))
{
fz/=10;
fm/=10;
}
else
{
break;
}
}
//实现第二步:约分。以下看起来有点麻烦,目的是为了减少算法的时间复杂的
while((fz%2==0)&&(fm%2==0))
{//将公约数2约尽
fz/=2;
fm/=2;
}
k=3;
for(;;)
{
while((fz%k==0)&&(fm%k==0))
{
fz/=k;
fm/=k;
}
k+=2;
if(k>(ZHENGSHU)sqrt(fz))
break;
}
//将整数部分加上,形成假分数。如果原数为不为0整数,则化成分母为1的假分数
//如果原数为0,则化成分子为0,分母为1。
if(fz==0)
{
fz=fh*zs;
fm=1;
}
else
{
fz=fh*(fz+fm*zs);
}
//结束
//显示一下结果
printf("%lf=%lld/%lld\n",fh*(zs+xs),fz,fm);
//printf("%lf=%ld/%ld\n",fh*(zs+xs),fz,fm);//32位
system("pause");//防止窗口一闪而退
return0;
}