Handle zero-like imaginary part as zero in to_r (#9581)
Fixes [Bug #5179]
This commit is contained in:
parent
89f0c0ceb5
commit
54a5b82944
12
complex.c
12
complex.c
@ -1841,9 +1841,11 @@ nucomp_to_f(VALUE self)
|
|||||||
*
|
*
|
||||||
* Complex.rect(1, 0).to_r # => (1/1)
|
* Complex.rect(1, 0).to_r # => (1/1)
|
||||||
* Complex.rect(1, Rational(0, 1)).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
|
* 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.
|
* Related: Complex#rationalize.
|
||||||
*/
|
*/
|
||||||
@ -1852,10 +1854,16 @@ nucomp_to_r(VALUE self)
|
|||||||
{
|
{
|
||||||
get_dat1(self);
|
get_dat1(self);
|
||||||
|
|
||||||
if (!k_exact_zero_p(dat->imag)) {
|
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",
|
rb_raise(rb_eRangeError, "can't convert %"PRIsVALUE" into Rational",
|
||||||
self);
|
self);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return f_to_r(dat->real);
|
return f_to_r(dat->real);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,8 +34,16 @@ describe "Complex#to_r" do
|
|||||||
end
|
end
|
||||||
|
|
||||||
describe "when the imaginary part is Float 0.0" do
|
describe "when the imaginary part is Float 0.0" do
|
||||||
|
ruby_version_is ''...'3.4' do
|
||||||
it "raises RangeError" do
|
it "raises RangeError" do
|
||||||
-> { Complex(0, 0.0).to_r }.should raise_error(RangeError)
|
-> { Complex(0, 0.0).to_r }.should raise_error(RangeError)
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
@ -1054,6 +1054,29 @@ class Complex_Test < Test::Unit::TestCase
|
|||||||
assert_raise(RangeError){Rational(Complex(3,2))}
|
assert_raise(RangeError){Rational(Complex(3,2))}
|
||||||
end
|
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
|
def test_to_c
|
||||||
c = nil.to_c
|
c = nil.to_c
|
||||||
assert_equal([0,0], [c.real, c.imag])
|
assert_equal([0,0], [c.real, c.imag])
|
||||||
|
Loading…
x
Reference in New Issue
Block a user