Handle zero-like imaginary part as zero in to_r (#9581)
Fixes [Bug #5179]
This commit is contained in:
parent
89f0c0ceb5
commit
54a5b82944
16
complex.c
16
complex.c
@ -1841,9 +1841,11 @@ nucomp_to_f(VALUE self)
|
||||
*
|
||||
* Complex.rect(1, 0).to_r # => (1/1)
|
||||
* Complex.rect(1, Rational(0, 1)).to_r # => (1/1)
|
||||
* Complex.rect(1, 0.0).to_r # => (1/1)
|
||||
*
|
||||
* Raises RangeError if <tt>self.imag</tt> is not exactly zero
|
||||
* (either <tt>Integer(0)</tt> or <tt>Rational(0, _n_)</tt>).
|
||||
* (either <tt>Integer(0)</tt> or <tt>Rational(0, _n_)</tt>)
|
||||
* and <tt>self.imag.to_r</tt> is not exactly zero.
|
||||
*
|
||||
* Related: Complex#rationalize.
|
||||
*/
|
||||
@ -1852,9 +1854,15 @@ nucomp_to_r(VALUE self)
|
||||
{
|
||||
get_dat1(self);
|
||||
|
||||
if (!k_exact_zero_p(dat->imag)) {
|
||||
rb_raise(rb_eRangeError, "can't convert %"PRIsVALUE" into Rational",
|
||||
self);
|
||||
if (RB_FLOAT_TYPE_P(dat->imag) && FLOAT_ZERO_P(dat->imag)) {
|
||||
/* Do nothing here */
|
||||
}
|
||||
else if (!k_exact_zero_p(dat->imag)) {
|
||||
VALUE imag = rb_check_convert_type_with_id(dat->imag, T_RATIONAL, "Rational", idTo_r);
|
||||
if (NIL_P(imag) || !k_exact_zero_p(imag)) {
|
||||
rb_raise(rb_eRangeError, "can't convert %"PRIsVALUE" into Rational",
|
||||
self);
|
||||
}
|
||||
}
|
||||
return f_to_r(dat->real);
|
||||
}
|
||||
|
@ -34,8 +34,16 @@ describe "Complex#to_r" do
|
||||
end
|
||||
|
||||
describe "when the imaginary part is Float 0.0" do
|
||||
it "raises RangeError" do
|
||||
-> { Complex(0, 0.0).to_r }.should raise_error(RangeError)
|
||||
ruby_version_is ''...'3.4' do
|
||||
it "raises RangeError" do
|
||||
-> { Complex(0, 0.0).to_r }.should raise_error(RangeError)
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is '3.4' do
|
||||
it "returns a Rational" do
|
||||
Complex(0, 0.0).to_r.should == 0r
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -1054,6 +1054,29 @@ class Complex_Test < Test::Unit::TestCase
|
||||
assert_raise(RangeError){Rational(Complex(3,2))}
|
||||
end
|
||||
|
||||
def test_to_r_with_float
|
||||
assert_equal(Rational(3), Complex(3, 0.0).to_r)
|
||||
assert_raise(RangeError){Complex(3, 1.0).to_r}
|
||||
end
|
||||
|
||||
def test_to_r_with_numeric_obj
|
||||
c = Class.new(Numeric)
|
||||
|
||||
num = 0
|
||||
c.define_method(:to_s) { num.to_s }
|
||||
c.define_method(:==) { num == it }
|
||||
c.define_method(:<) { num < it }
|
||||
|
||||
o = c.new
|
||||
assert_equal(Rational(3), Complex(3, o).to_r)
|
||||
|
||||
num = 1
|
||||
assert_raise(RangeError){Complex(3, o).to_r}
|
||||
|
||||
c.define_method(:to_r) { 0r }
|
||||
assert_equal(Rational(3), Complex(3, o).to_r)
|
||||
end
|
||||
|
||||
def test_to_c
|
||||
c = nil.to_c
|
||||
assert_equal([0,0], [c.real, c.imag])
|
||||
|
Loading…
x
Reference in New Issue
Block a user