您的位置:首页 > 其它

小数转分数

2015-12-19 00:00 323 查看
所有分数都可以表示成小数,但是小数中只有有限小数、无限循环小数可以表示成分数,无限不循环小数不能表示成分数。

有限小数改写成分数:分子数小数部分的数,分母是10的分子长度的次幂;

纯循环小数改写成分数:分子是一个循环节的数字组成的数,分母各位数字都是9,9的个数与循环节中的数字的个数相同;

混循环小数改写成分数:分成有限小数部分和循环节部分处理,各部分同上。

最后找到分子、分母的最大公约数,把分数化成最简分数即可。

#include <stdio.h>
#include <string.h>

/* 函数功能:解析字符串为分数
* 参数表:strNum = 字符串,格式为 *.*(*),括号内为循环节
*         intgr  = 整数部分
*         nmrtr  = 分子
*         dnmtr  = 分母
* 返回值:0      = 输入错误(括号未匹配)
*         1      = 解析成功
*/

char fraction(char *strNum, int *intgr, unsigned *nmrtr, unsigned *dnmtr)
{
char *pDot = strchr(strNum, '.');            // 小数点的位置
char *pLeftBracket = strchr(strNum, '(');    // 左括号的位置
char *pRightBracket = strchr(strNum, ')');   // 右括号的位置
char *p;

*intgr = 0;
*nmrtr = 0;
*dnmtr = 1;

// 先处理整数部分
p = (strNum[0] == '-' ? strNum + 1 : strNum);
while((NULL != pDot && p < pDot) || (NULL == pDot && *p))
*intgr = 10 * *intgr +  *p++ - '0';
if(strNum[0] == '-')
*intgr = -*intgr;

// 再处理小数部分
if(NULL == pDot)
return 1;
p = pDot + 1;
// 没有括号 = 有限小数:转换成10的倍数作为分母的分数
if(NULL == pLeftBracket && NULL == pRightBracket)
{
while(*p)
{
*nmrtr = 10 * *nmrtr +  *p++ - '0';
*dnmtr *= 10;
}
}
// 有一对匹配的括号 = 无限循环小数
else if(NULL != pLeftBracket && NULL != pRightBracket)
{
unsigned temp1 = 0, temp2 = 0, temp3 = 1, temp4 = 1;

// 有限小数部分:同有限小数
while(p < pLeftBracket)
{
temp1 = temp1 * 10 + *p++ - '0';
temp3 *= 10;
}
// 循环节部分:分子为一个循环节,分母为循环节长度个数的 9
p = pLeftBracket + 1;
while(p < pRightBracket)
{
temp2 = temp2 * 10 + *p++ - '0';
temp4 *= 10;
}
temp4--;
// 合并:t1/t3 + t2/(t3*t4)
*nmrtr = temp1 * temp4 + temp2;
*dnmtr = temp3 * temp4;
}
// 只有一个括号 = 输入错误
else
{
return 0;
}

// 辗转相除法求分子、分母的最大公约数
unsigned temp, gcd = *dnmtr, remainder = *nmrtr;
while(remainder)
{
temp = gcd % remainder;
gcd = remainder;
remainder = temp;
}
*nmrtr /= gcd;
*dnmtr /= gcd;

return 1;
}

int main(int argc, char **argv)
{
int intgr;
unsigned nmrtr, dnmtr;

if(argc == 2)
{
fraction(argv[1], &intgr, &nmrtr, &dnmtr);
if(nmrtr > 0)
printf("%s = %d %d/%d", argv[1], intgr, nmrtr, dnmtr);
else
printf("%s = %d", argv[1], intgr);
}
else
{
printf("Usage : %s *.*(*)", argv[0]);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: