我已经创建了一个函数,它将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"
?
答案 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,则分数已经减少,您只需去掉小数位并返回给定的数。