编程c语言分数转小数,小数转分数 - 四彩的个人空间 - OSCHINA - 中文开源技术交流社区...

所有分数都可以表示成小数,但是小数中只有有限小数、无限循环小数可以表示成分数,无限不循环小数不能表示成分数。

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

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

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

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

#include 

#include 

/* 函数功能:解析字符串为分数

* 参数表: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 

*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 

{

temp1 = temp1 * 10 + *p++ - '0';

temp3 *= 10;

}

// 循环节部分:分子为一个循环节,分母为循环节长度个数的 9

p = pLeftBracket + 1;

while(p 

{

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;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值