Skip to content

Commit

Permalink
Implement 1.9 Integer#round
Browse files Browse the repository at this point in the history
Doesn't follow MRI's goofy NUM2INT RangeError logic.
  • Loading branch information
jfirebaugh committed Dec 4, 2011
1 parent 5abbb1c commit a49605a
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 6 deletions.
1 change: 0 additions & 1 deletion kernel/common/integer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ def to_i
end

alias_method :to_int, :to_i
alias_method :round, :to_i
alias_method :truncate, :to_i
alias_method :ceil, :to_i
alias_method :floor, :to_i
Expand Down
3 changes: 3 additions & 0 deletions kernel/common/integer18.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class Integer
alias_method :round, :to_i
end
29 changes: 29 additions & 0 deletions kernel/common/integer19.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,33 @@
class Integer
def round(ndigits=undefined)
return self if ndigits.equal? undefined

ndigits = Rubinius::Type.coerce_to(ndigits, Integer, :to_int)
if ndigits > 0
to_f
elsif ndigits == 0
self
else
ndigits = -ndigits

# We want to return 0 if 10 ** ndigits / 2 > self.abs, or, taking
# log_256 of both sides, if log_256(10 ** ndigits / 2) > self.size.
# We have log_256(10) > 0.415241 and log_256(2) = 0.125, so:
return 0 if 0.415241 * ndigits - 0.125 > size

f = 10 ** ndigits
h = f / 2
r = self % f
n = self - r

unless self < 0 ? r <= h : r < h
n = n + f
end

n
end
end

alias_method :magnitude, :abs

#
Expand Down
1 change: 1 addition & 0 deletions kernel/common/load_order18.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ numeric18.rbc
ctype.rbc
precision.rbc
integer.rbc
integer18.rbc
bignum.rbc
block_environment.rbc
bytearray.rbc
Expand Down
5 changes: 0 additions & 5 deletions spec/tags/19/ruby/core/integer/round_tags.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1 @@
fails:Integer#round rounds itself as a float if passed a positive precision
fails:Integer#round returns itself if passed zero
fails:Integer#round returns itself rounded if passed a negative value
fails:Integer#round returns 0 if passed a big negative value
fails:Integer#round raises a RangeError when its argument can not be converted to a Fixnum
fails:Integer#round raises a TypeError when its argument can not be converted to an Integer

0 comments on commit a49605a

Please sign in to comment.