Skip to content

Commit d248588

Browse files
committed
Fix Float#<=> when comparing Infinity to other infinite values
1 parent 950ddf3 commit d248588

File tree

3 files changed

+35
-0
lines changed

3 files changed

+35
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ Compatibility:
3535
* Implement `IO#set_encoding_by_bom` (#2372, pawandubey).
3636
* Implemented `Enumerator::Lazy#with_index` (#2356).
3737
* Implement `rb_backref_set`.
38+
* Fix `Float#<=>` when comparing `Infinity` to other `#infinite?` values.
3839

3940
Performance:
4041

spec/ruby/core/float/comparison_spec.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,28 @@ def coerce(other)
6363
it "returns 1 when self is negative and other is -Infinity" do
6464
(-Float::MAX.to_i*2 <=> -infinity_value).should == 1
6565
end
66+
67+
it "returns 0 when self is Infinity and other other is infinite?=1" do
68+
obj = Object.new
69+
def obj.infinite?
70+
1
71+
end
72+
(infinity_value <=> obj).should == 0
73+
end
74+
75+
it "returns 1 when self is Infinity and other is infinite?=-1" do
76+
obj = Object.new
77+
def obj.infinite?
78+
-1
79+
end
80+
(infinity_value <=> obj).should == 1
81+
end
82+
83+
it "returns 1 when self is Infinity and other is infinite?=nil (which means finite)" do
84+
obj = Object.new
85+
def obj.infinite?
86+
nil
87+
end
88+
(infinity_value <=> obj).should == 1
89+
end
6690
end

src/main/ruby/truffleruby/core/numeric.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,17 @@ def redo_compare(meth, right)
236236
a <=> b
237237
end
238238

239+
# only used by Float#<=>
239240
private def redo_compare_bad_coerce_return_error(right)
241+
if self.infinite? and !Primitive.undefined?(val = Truffle::Type.check_funcall(right, :infinite?))
242+
if val
243+
cmp = val <=> 0
244+
return self > 0.0 ? (cmp > 0 ? 0 : 1) : (cmp < 0 ? 0 : -1)
245+
else
246+
# right.infinite? returned false or nil, which means right is finite
247+
return self > 0.0 ? 1 : -1
248+
end
249+
end
240250
b, a = math_coerce(right, :bad_coerce_return_error)
241251
return nil unless b
242252
a <=> b

0 commit comments

Comments
 (0)