分割双打时可能出错

时间:2013-12-22 09:15:09

标签: java double divide

我想检查相等的2个分数。我认为我写的方法不正确,因为可能会失去准确性。我是对还是错?

public boolean equals(Rational r) {
    return (double) numerator / denominator == (double) r.numerator / r.denominator;
}

6 个答案:

答案 0 :(得分:5)

我认为这会更好:

public boolean equals(Rational r) {
  return numerator * r.denominator == r.numerator * denominator;
}

答案 1 :(得分:2)

你是对的,这种检查在很多情况下会失败。

使其工作的唯一方法是将结果转换为BigDecimal或String,然后比较或定义允许的错误 - 即:

public boolean equals(Rational r) {
    double c1 = ((double) numerator) / denominator;
    double c2 = ((double) r.numerator) / r.denominator;
    return c2 > (c1-allowedError) && c2 < (c1+allowedError);
}

答案 2 :(得分:1)

你可以这样做

public boolean equals(Rational r) {
    return numerator * r.denominator == r.numerator * denominator;
}

答案 3 :(得分:1)

如果你的理性减少了分子和分母之外的所有常见因素,那么你可以这样做:

return (numerator == r.numerator) && (denominator == r.denominator);

如果您的理性已完成该分解,那么我建议您实施一个允许您这样做的GCD功能。然后将缩小的numeratordenominator与缩减的r.numerator和r.denominator进行比较。

示例,假设int是理性分子和分母的基础类型:

int gcd_lhs = gcd( numerator,   denominator   );
int gcd_rhs = gcd( r.numerator, r.denominator );

int lhs_red_num = numerator   / gcd_lhs;
int lhs_red_den = denominator / gcd_lhs;
int rhs_red_num = r.numerator   / gcd_rhs;
int rhs_red_den = r.denominator / gcd_rhs;

return (lhs_red_num == rhs_red_num) && (lhs_red_den == rhs_red_den);

这种方法的优点是在所有情况下都是精确的,并且它永远不会超过你用于分子和分母的基础类型的精度。

依赖乘法或除了GCD风险以外的值除以基础类型中可用精度的方法。 (除非首先转换为double,否则可以通过生成一个必须舍入以适应可用位的重复二进制小数来“溢出”可用精度。除以GCD总是精确的,并保持为整数除法。 )

可以通过使用BigInteger类型并应用交叉乘法方法来缓解这种情况。这有其自身的成本。如果您已经使用BigInteger来存储分子和分母,那么这可能是最简单的方法。

答案 4 :(得分:0)

执行此操作的一种方法如下:

boolean eq = Math.abs( (double) numerator / denominator - 
                       (double) r.numerator / r.denominator ) < EPS;

其中

EPS是一些小的正常数,例如EPS=0.00001

如果eq变量设置为true,则表示您的数字“相等” 除了您想忽略的可能的精度错误。

当然在Java操作中有浮点
与许多其他语言一样,数字不是100%精确
或者,正如其他人在此建议的那样,
你可以决定不使用双打 特别的任务/但你不能总是避免它们;)/

答案 5 :(得分:0)

在双元浮点系统中使用==和双精度可能是危险的,因为某些分数(包括十进制中可表达的一些分数)can't be expressed

你可以重新排列方程,这样你就不需要双打(假设你的分子和分母是整数)

r.denominator*numerator==denominator*r.numerator