浮点数的分数表达
2015-10-18 13:09
239 查看
Description
在计算机中,用float或double来存储小数有时不能得到精确值,若要精确表达一个浮点数的计算结果,最好用分数来表示小数,有限小数或无限循环小数都可以转化为分数,无限循环小数的循环节用括号标记出来。如:
0.9 = 9/10
0.(3) = 0.3(3) = 0.3(33) = 1/3
当然一个小数可以用好几种分数形式来表示,我们只感兴趣最简的分数形式(即分母最小),如:
0.3(33) = 1/3 = 3/9
因为任何一个数都可以转化为一个整数和一个纯小数之和,整数部分较为简单无需做额外处理,只要将纯小数部分转
化为分数形式,整数部分的分数部分就很简单了。
现在给定一个正的纯小数(这个纯小数为有限小数或无限循环小数),请你以最简分数形式来返回这个纯小数。
输入格式
给定一个纯小数,若是无限循环小数,用括号标记循环节,输入小数表达不超过100个字符。输出格式
输出:化为最简分数形式,分子在前,分母在后,中间空格连接。输入样例
0.3(33)输出样例
1 3本题的解题思路
考虑输入的是纯小数,先暂时不考虑分子和分母有公因子的情况。(1) 假设有限小数:X = 0.a1a2…an,式中的a1,a2,…,an都是0~9的数字。
X = 0.a1a2…an = a1a2…an/10^n
(2) 假设无限循环小数:X = 0.a1a2…an(b1b2…bm),式中的a1,a2,…,an, b1,b2,…,bm都是0~9的数字,括号为循环节。
第一步,先将X化为只有循环部分的纯小数。
X = 0.a1a2…an(b1b2…bm)
(10^n)*X = a1a2…an + 0.(b1b2…bm)
X = (a1a2…an + 0.(b1b2…bm)) / (10^n)
上式中,a1a2…an是整数部分,容易解决。重点考虑小数部分0.(b1b2…bm)如何化为分数形式,再加上整数部分即可。
第二步,考虑Y = 0.(b1b2…bm),将Y化为分数,
(10^m)*Y = b1b2…bm + 0.(b1b2…bm)
((10^m)-1)*Y = b1b2…bm
Y = b1b2…bm / ((10^m)-1)
将第二步的Y带入第一步的X,可得:
X = (a1a2…an+Y)/(10^n) = ((a1a2…an)((10^m)-1) + (b1b2…bm)) / (((10^m)-1)(10^n))
此时,可以将任何一个有限小数或无限循环小数,化为分数表示,分数的分子和分母如上分析的公式。但此时
的分子分母未必是最简化的,对分子分母再进行约分,删去公共的因子,A/B = (A/GCD(A,B))/(B/GCD(A,B)),
化为简单形式。
观察数据
0.3(33) —>1/30.(368421052631578947) —>7 / 19
0.285714(285714) —> 2/ 7
0.35(789) —> 5959 / 16650
以0.35(789)为例
分子=35789-35=35754
分母=99900
分子分母最大公约数6
最后分子=35754/6=5959
最后分母=99900/6=16650
以0.3(33)为例
分子=333-3=330
分母=990
分子分母最大公约数330
最后分子=1
最后分母=3
java代码
import java.util.Scanner; public class Float { private static Scanner input; public static void main(String []args){ String a; int l=0,r=0,d; Long c=(long) 1,b; input = new Scanner(System.in); a = input.next(); if(a.contains("(")){ r=a.indexOf(")"); l=a.indexOf("("); d = r-l-1; a=a.replace("(",""); a=a.replace(")",""); a=a.substring(2,a.length()); b = Long.parseLong(a); if(l!=2){ b=(long) (b-Math.floor(b/Math.pow(10,d))); } while(d>=1){ c = c*10; d--; } c--; while(l>2){ c *=10; l--; } }else{ c =(long) (c*Math.pow(10,a.length()-2)); a=a.substring(2,a.length()); b = Long.parseLong(a); } System.out.println(b/gcd(b,c)+" "+c/gcd(b,c)); } public static long gcd(long m, long n) //求两个数的最小公约数 { while (true) { if ((m = m % n) == 0) return n; if ((n = n % m) == 0) return m; } } }
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树
- [原创]java局域网聊天系统