【问题标题】:Floating point errors浮点错误
【发布时间】:2014-02-18 04:53:58
【问题描述】:

我遇到了浮点问题。一个双。例如,Java 中的 56 实际上可能存储为 .56000...1。

我正在尝试将小数转换为分数。我尝试使用连分数来做到这一点

Continuous Fractions

但由于计算机如何存储和四舍五入的小数,我使用该方法的答案不准确。

我尝试了另一种方法:

public static Rational rationalize(double a){
        if(a>= 1){
        //throw some exception
    }
    String copOut = Double.toString(a);

    int counter = 0;
    System.out.println(a);
    while(a%1 != 0 && counter < copOut.length() - 2){
        a *= 10;
        counter++;
    }
    long deno = (long)Math.pow(10,counter);//sets the denominator
    Rational frac = new Rational((long)a,deno)//the unsimplified rational number
    long gcd = frac.gcd();
    long fnum = frac.getNumer();//gets the numerator 
    long fden = frac.getDenom();//gets the denominator
    frac = new Rational(fnum/gcd, fden/gcd);
    return frac;    
}

我正在使用字符串来查找小数的长度,以确定我应该乘以 10 的次数。我后来截断了小数。这让我得到了正确的答案,但感觉不是正确的方法? 有人可以建议这样做的“正确”方法吗?

【问题讨论】:

  • 这里的第一个问题是 inputdouble. 所以在你的任何代码执行之前你已经失去了精度。想想BigDecimal.

标签: java floating-point rational-numbers


【解决方案1】:

实际上你做得很好.. 但是如果输入是关于11.56 的东西,这将失败。在这里你需要做copOut.length() - 3

要使其动态使用String#split()

String decLength = copOut.split("\\.")[1]; //this will result "56" (Actual string after decimal)

现在你只需要做

while(a%1 != 0 && counter < decLength.length()){
        a *= 10;
        counter++;
    }

如果你想删除循环然后使用

long d = (long)Math.pow(10,decLength.length());
 a=a*d;

【讨论】:

    猜你喜欢
    • 2016-03-15
    • 1970-01-01
    • 2012-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-17
    相关资源
    最近更新 更多