C语言将循环小数/有限小数转换为分数

文章目录

  • 数学基础
  • 编程思路
  • 代码

数学基础

早在小学的时候我就对循环小数非常感兴趣,加上初中和高中对循环小数可以说有一定基础研究,因此想到写一个将循环下小数转换为分数的程序,非常有意思,并且对初学者来说,它的输入输出格式的转换也是一大难点。
首先必须明确一点,循环小数必定可以转换为分数,原因在于循环小数总可以分解为不循环的有限部分+循环的无限部分。前者对应一个分数,后者可以写成一个收敛的等比数列的和,也必定是可以转换为一个分数的。例如0.234343434…,有限部分为0.2=1/5,无限部分为0.0343434…=0.034/(1-0.01)=34/990=17/495;0.2343434…=1/5+17/495=116/495。同理,0.879879879…=0.879/(1-0.001)=879/999。
所以任何一个循环小数都可以化为分数,并且通过上述两个例子,我们也对如何转换有了一个初步的了解。

编程思路

  1. 首先我们得设置一下输入的格式,有限部分和循环部分显然是要分开的,为了方便起见,我在程序里设置的是空格分开。 需要的头文件分别是**<math.h>,<stdio.h>,<stdlib.h>,<string.h>**。
  2. 第二,由于是纯数学运算,来不得半点近似,所有的分数运算我们都需要保留分子和分母,所以保存一个小数的变量是两个整形——分子(num)和分母(den),不妨定义一个分数(Decimal)结构体类型,里面包含整形数据的分子和分母。
  3. 虽然说处理的是整形变量,但是由于我们输入是浮点数,扫描会带来麻烦,所以扫描的时候我还是采用%s的格式一股气扫进去的,根据小数点来个划分。这里还用到了<stdlib.h>当中的itoa和atoi函数,这两个函数可以求出正数的长度。当然,你也可以用<math.h>当中的log10()来求取长度,这两种方法在我的程序中皆有涉及。
  4. 对于分数的处理,显然是要用到化简函数了,化简分数无非就是分子分母同时除以它们的最大公约数,因此需要写一个辗转相除法求最大公约数的程序。分数相加的原理也很简单,先对每个分数化简,再按照手算的方法相加,最后调用化简分数的函数对其化简即可。
  5. 计算有限小数部分的方法和循环小数部分的不同,这一点在第一部分里面已经提到,分别获取有限部分的位长以及循环部分的位长很关键。例如转换一个小数0.2343434…,假设输入0.2 34代表了这个循环小数,用scanf("%s%s",str1,str2)函数输入,那么strlen(str2)就是循环部分的位长。有限部分的位长,比循环部分的计算稍微复杂一些,你可以利用strstr函数舍掉小数点前面的部分,当然,小数点前面的部分不代表就没有用,毕竟我们输入的小数有可能大于1,因此按照如下方法处理即可:
float f1;
int integer,dec_length,cir_length;
f1=atof(str1);
integer=(int)f1;//整数部分
dec_length=strlen(strstr(str1,".")+1);//有限小数部分的长度,strstr(str1,".")+1是小数点后的一个数的指针,再取strlen即小数部分的长度
cir_length=strlen(str2);//循环小数部分长度

这几步非常关键,牵涉到我们的分母到底应该怎么写,如果分母有差错,那之后的化简都是白搭。

  1. 这里需要说明的是,由于我们是按照小数点分隔的,没有考虑到负号的情况,所有本程序暂时只支持输入正的小数,当然即使是负小数,也能很容易通过本程序找到答案。

代码

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h> 
struct Decimal{int num;int den;
};//定义分数结构体 
void simplify(int *num,int *den);//化简一个分数的分子和分母
int GCD(int a,int b);//求两个数的最大公约数 
int main()
{char str1[100],str2[100],int1[10];//存放两个分数的字符串,后续再处理  float f1; int integer,dec1,num,den;//integer是整个小数的整数部分,dec1是有限部分的小数部分(不含小数点的),num和den分别是最终结果分数的分子和分母struct Decimal Dec,Cir;//小数部分对应的分数结构体(有限部分+循环部分) printf("*******小数转换为分数的实验*********\n");printf("请输入一串小数,如有循环节,请和有限部分用空格隔开,如没有循环节,请用0代替。\n");printf("例如0.2 34代表0.234343434......,3.8753 0代表3.8753\n");//对输入的一个简单说明scanf("%s%s",str1,str2);//这里不能用%f扫入,否则将不知道小数长度 f1=atof(str1);//将输入的字符转换为浮点数 integer=(int)f1;//取整数部分dec1=atoi(strstr(str1,".")+1);itoa(integer,int1,10);//integer转为字符串,方便计算长度 Dec.num=dec1;//有限小数的小数部分(注意是整形的,指的是不含小数点的小数部分)Dec.den=pow(10,strlen(str1)-strlen(int1)-1);Cir.num=atoi(str2);Cir.den=pow(10,strlen(str2))-1;Cir.den*=pow(10,(int)(log10(dec1)+1));if(Cir.num==0){simplify(&Dec.num,&Dec.den);num=Dec.num+integer*Dec.den;den=Dec.den;simplify(&num,&den);if(integer!=0)printf("转换为带分数的结果为:%d+%d/%d\n",integer,Dec.num,Dec.den);printf("转换为分数的结果为:%d/%d\n",num,den); return 0;} //如果循环小数是0,直接转换有限部分即可,否则需要将循环部分加以转换,并与有限部分的分数相加 simplify(&Dec.num,&Dec.den);simplify(&Cir.num,&Cir.den);den=Dec.den*Cir.den;num=Dec.num*Cir.den+Dec.den*Cir.num;if(integer!=0)printf("转换为带分数结果为:%d+%d/%d\n",integer,num,den);num+=den*integer;printf("转换为分数结果为:%d/%d\n",num,den); return 0;
} 
int GCD(int a,int b)
{//利用辗转相除法求两个数的最大公约数 if(a==1||b==1)return 1;int t;if(a<b){t=a;a=b;b=t;}//保证a是大数while(b>0){t=b;//t临时存放小数b=a%b;//小数是上一次两个数相除的余数a=t;//大数是上一次相除的小数}return a;
}
void simplify(int *num,int *den)
{int gcd=GCD(*num,*den);*num=*num/gcd;*den=*den/gcd;
}

那么好,我们来输入一个循环小数进行验证,如果位数比较多的话,出来的应该是个变态的答案,当然你要相信自己是对的:
程序执行画面

下面我们用Win10自带的计算器验证一下(科学模式)
科学计算器输出结果
说明我们的结果没问题,大功告成。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/544548.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

升级了 Windows 11 正式版,有坑吗?

作者 | 王磊来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;今天磊哥去公司上班&#xff0c;惊喜的发现 Windows 提示更新了&#xff0c;并且是 Windows 11 正式版&#xff0c;这太让人…

C语言结构体的应用——万年历

文章目录万年历简述代码万年历简述 万年历——就是输入一个日期可以查询是星期几&#xff0c;这个功能看起来很普通&#xff0c;但是如果用程序时间的话&#xff0c;还是药费一番周折: 我们需要保存一个固定的日期&#xff0c;存放它是星期几&#xff0c;输入一个自定义的日期…

@Value竟然能玩出这么多花样

前言对于从事java开发工作的小伙伴来说&#xff0c;spring框架肯定再熟悉不过了。spring给开发者提供了非常丰富的api&#xff0c;满足我们日常的工作需求。如果想要创建bean实例&#xff0c;可以使用Controller、Service、Repository、Component等注解。如果想要依赖注入某个对…

C语言实现线性动态(单向)链表【详细步骤】

文章目录什么是链表为什么不用结构体数组链表的操作创建表删除元素插入元素代码及运行结果什么是链表 链表是数据结构里面的一种&#xff0c;线性链表是链表的一种&#xff0c;线性链表的延伸有双向链表和环形链表。在编程语言中优化数据结构可以在处理大数据时大大降低程序的…

移动前端经验小结

1. 移动端头部标签 head meta <!DOCTYPE html> <!-- 使用 HTML5 doctype&#xff0c;不区分大小写 --> <html lang"zh-cmn-Hans"> <!-- 更加标准的 lang 属性写法 http://zhi.hu/XyIa --> <head><!-- 声明文档使用的字符编码 -->…

再见收费的Navicat!操作所有数据库靠它就够了!

为了快速管理数据库&#xff0c;我们一般都会选择一款顺手的数据库管理工具。Navicat、DataGrip虽然很好用&#xff0c;但都是收费的。今天给大家推荐一款免费、功能强大的数据库管理工具DBeaver&#xff0c;希望对大家有所帮助&#xff01;DBeaver简介 DBeaver是一款开源的数据…

查找两个字符串中相同字符串_使两个字符串相同的最低成本

查找两个字符串中相同字符串Problem statement: 问题陈述&#xff1a; Given two strings string1 and string2 find the minimum cost required to make the given two strings identical. We can delete characters from both the strings. The cost of deleting a characte…

Matlab对指定参数的曲线进行非线性拟合

Matlab拟合曲线的方式 Matlab拟合曲线的方式有很多种&#xff0c;有三次样条插值、线性插值、多项式拟合等等。多项式拟合由于函数由f(x)anxnan−1xn−1...a1xa0f(x)a_nx^na_{n-1}x^{n-1}...a_1xa_0f(x)an​xnan−1​xn−1...a1​xa0​组成&#xff0c;若采用最小二乘法拟合&a…

MyBatis原生批量插入的坑与解决方案!

作者 | 王磊来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;前面的文章咱们讲了 MyBatis 批量插入的 3 种方法&#xff1a;循环单次插入、MyBatis Plus 批量插入、MyBatis 原生批量插入…

系统结构图 数据结构_数据结构图简介

系统结构图 数据结构What you are going to learn? 你要学什么&#xff1f; In this article, we learn about the introduction to Graphs in Data Structure and Algorithm. 在本文中&#xff0c;我们将了解图在数据结构和算法中的介绍 。 What are the components in Gra…

Matlab仿真PID控制(带M文件、simulink截图和参数分析)

文章目录0.符号说明1.如何根据连续系统建立差分方程1.1.获取连续系统的传递函数1.2.获取离散系统的传递函数1.3.转换为差分方程2.基本PID控制原理3.比较PID输出&#xff0c;分析参数产生的影响4.改进PID算法&#xff08;遇限削弱积分法&#xff09;5.simulink仿真0.符号说明 y…

再见 Postman!Apifox 才是 YYDS!

作为开软件开发从业者&#xff0c;API 调试是必不可少的一项技能&#xff0c;在这方面 Postman 做的非常出色。但是在整个软件开发过程中&#xff0c;API 调试只是其中的一部分&#xff0c;还有很多事情 Postman 无法完成&#xff0c;或者无法高效完成&#xff0c;比如&#xf…

Matlab【可视化作图】绘制线电压相电压辅助线

目录引言绘图原理采点绘图设置坐标轴标尺引言 学习电力电子的同学可能在私下里练习的时候非常需要三相线电压和相电压的辅助线。最近我随便找了一本书把Matlab可视化编程恶补了一下&#xff0c;给大家介绍一下这个波形辅助线是怎么做的。 三相线电压辅助线就是一组相位相差60的…

SpringBoot实现Excel导入导出,好用到爆,POI可以扔掉了!

在我们平时工作中经常会遇到要操作Excel的功能&#xff0c;比如导出个用户信息或者订单信息的Excel报表。你肯定听说过POI这个东西&#xff0c;可以实现。但是POI实现的API确实很麻烦&#xff0c;它需要写那种逐行解析的代码&#xff08;类似Xml解析&#xff09;。今天给大家推…

Facebook升级到MySQL 8.0付出的代价

近日&#xff0c;Facebook 官博公布了他们的数据库版本从 MySQL 5.6 升级到了 MySQL 8.0&#xff0c;并且在官博记录了复盘详细的升级过程。Facebook 称&#xff0c;他们最近的一次大版本升级到 MySQL 5.6 花了一年多时间才完成&#xff0c;还在 5.6 版上开发 LSM 树存储引擎&a…

Matlab制作朱利表

朱利判据 其中 {bn−kan−k−ana0∗akcn−kbn−k−bnb0∗bk...qn−kpn−k−pnp0∗pk\begin{cases} b_{n-k}a_{n-k}-\frac{a_n}{a_0}*a_k\\ c_{n-k}b_{n-k}-\frac{b_n}{b_0}*b_k\\ ...\\ q_{n-k}p_{n-k}-\frac{p_n}{p_0}*p_k \end{cases}⎩⎪⎪⎪⎨⎪⎪⎪⎧​bn−k​an−k​−a0…

高并发下秒杀商品,必须知道的9个细节

高并发下如何设计秒杀系统&#xff1f;这是一个高频面试题。这个问题看似简单&#xff0c;但是里面的水很深&#xff0c;它考查的是高并发场景下&#xff0c;从前端到后端多方面的知识。秒杀一般出现在商城的促销活动中&#xff0c;指定了一定数量&#xff08;比如&#xff1a;…

最小拍控制系统详细解读(阶跃输入+速度输入2个案例)【Simulink仿真】

目录索引1.符号说明与结构框图2.最小拍控制系统构造原则2.1数字控制器D(z)的构造3.简单控制对象的最小拍控制器设计3.1阶跃输入3.2速度输入1.符号说明与结构框图 y(k)——系统响应输出的离散值u(k)——数字PID控制输出的离散值r(k)——期望输出的离散值&#xff08;事先已知&a…

SpringBoot官方热部署和远程调试神器,真带劲!

平时使用SpringBoot开发应用时&#xff0c;修改代码后需要重新启动才能生效。如果你的应用足够大的话&#xff0c;启动可能需要好几分钟。有没有什么办法可以加速启动过程&#xff0c;让我们开发应用代码更高效呢&#xff1f;今天给大家推荐一款SpringBoot官方的热部署工具spri…

【Python】输入任意个数元素并保存至列表

目录1.导入任意个数元素到列表1.1.编程思路1.2.代码片2.查找一个重复元素在列表中的所有位置2.1.编程思路2.2代码片1.导入任意个数元素到列表 1.1.编程思路 输入未知个数的元素需要用列表来存储&#xff0c;由于Python具有内存的动态分配能力&#xff0c;列表不需要手动动态分…