检查双倍是否= 1/3

时间:2016-03-25 22:31:43

标签: java math

我已经创建了一个函数,它将double转换为Java中的简化部分:

public static int gcm(int a, int b) {
    return b == 0 ? a : gcm(b, a % b);
}
public static String toFraction(double d) {
    int decimals = String.valueOf(d).split("\\.")[1].length();
    int mult = (int) Math.pow(10, decimals);
    int numerator = (int) (d * mult);
    int denominator = mult;
    // now simplify
    int gcm = gcm(numerator, denominator);
    numerator /= gcm;
    denominator /= gcm;
    return numerator + "/" + denominator;
}

它有效,但如果我使用toFraction(1.0/3),这将是可以理解的,返回"715827882/2147483647"。我该如何解决此问题才能返回"1/3"

3 个答案:

答案 0 :(得分:6)

您必须允许某个错误,并且并非所有分数都可以精确地表示为标量值。

View::composer('*', function($view)
{
    $view->with('menuCategories', Category::all());
});

打印

$menuCategories

注意:这可以找到PI的21 / 7,333 / 106和355/113近似值。

答案 1 :(得分:3)

没有double值等于三分之一,因此您的程序可以打印1/3的唯一方法是,如果您更改方法的规范以支持" nice&#34 ;答案而不是技术上正确的答案。

你可以做的一件事就是为答案选择一个最大分母,比如100,然后用分母100或更小的单位返回最接近的分数。

以下是使用Java 8流实现此目的的方法:

public static String toFraction(double val) {
    int b = IntStream.rangeClosed(1, 100)
                     .boxed()
                     .min(Comparator.comparingDouble(n -> Math.abs(val * n - Math.round(val * n))))
                     .get();
    int a = (int) Math.round(val * b);
    int h = gcm(a, b);
    return a/h + "/" + b/h;
}

对此没有好办法。 double对这类事情并不是很好。请注意,BigDecimal也不能代表1/3,因此您在该类中遇到同样的问题。

答案 2 :(得分:0)

有很好的方法可以解决这个问题,但您需要查看特殊情况。例如,如果分子为1,则分数已经减少,您只需去掉小数位并返回给定的数。

相关问题