Bug #8894

Fixnum#quo returns wrong result when given a float

Added by Marc-Andre Lafortune 7 months ago. Updated 7 months ago.

[ruby-core:57125]
Status:Open
Priority:Normal
Assignee:-
Category:core
Target version:-
ruby -v:p195 Backport:1.9.3: UNKNOWN, 2.0.0: UNKNOWN

Description

Fixnum#quo is buggy.

2.quo(2.0) # => Rational(2, 2)

1) Should return a float, not a rational
2) Moreover, that rational is invalid as it is not reduced.

Noticed by David MacMahon


Related issues

Related to ruby-trunk - Bug #5515: Integer#quo(aFloat) の結果が Rational になる Closed 10/30/2011

History

#1 Updated by Marc-Andre Lafortune 7 months ago

Issue is actually with Rational#/ that apparently makes a special case of float values that are "multiples" of the denominator, so that:

Rational(6) / 2.0 # => Rational(6, 2)

Putting aside the bug that the Rational returned is not reduced, I feel it is the wrong to return a Rational for many reasons.

1) A float is imprecise; other than very special cases one should not obtain exact values whenever one is involved in the calculation.
2) Inconsistent with Rational(5) / BigDecimal(2) that returns (correctly) a BigDecimal)
3) Inconsistent with Rational(6) / 1.5, that returns which won't return 4 nor Rational(4)

Is there any reason we should keep that special case?

diff --git a/rational.c b/rational.c
index 652f5ac..f8284d9 100644
--- a/rational.c
+++ b/rational.c
@@ -959,9 +959,6 @@ nurat_div(VALUE self, VALUE other)

        if (isnan(x)) return DBL2NUM(NAN);
        if (isinf(x)) return INT2FIX(0);
  • if (x != 0.0 && modf(x, &den) == 0.0) {
  • return rbrationalraw2(dat->num, fmul(rbdbl2big(den), dat->de
  • } } return rbfuncall(fto_f(self), '/', 1, other); }

Also available in: Atom PDF