您的位置:首页 > 编程语言 > Java开发

浮点数的分数表达

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/3

0.(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 算法